How to write code in python (from a vb net guy) - python

I am used to vb.net. I am learning python 3.6/7, as I understand it code writing is in either:
functions that return a result
functions that return a None
In a modules (no functions), ie run the module.py
In a class ie run the class.ID.function (ref (1) and (2))
In .Net you can run code in a function and a sub routine, so python has no sub routines, just functions returning None.
Is this correct?

Every function in python return some value, if you don't specify the return value then it will implicitly return None. So there is no distinction like sub or function in python.

Like other programming languages, in Python:
To let a function return a value, you have to use the return statement.
But if you don't specify the return value then it will simply return Nothing.

According to Wikipedia, In computer programming, a subroutine is a sequence of program instructions that performs a specific task, packaged as a unit. This unit can then be used in programs wherever that particular task should be performed.
So, in python a function can return any kind of value, objects or even None. A function returns None in two cases :
You write return None or return at the end of the function.
def some_func():
#do anything and return None
#you can write "return" instead "return None"
return None
some_var = some_func()
#There is no output to the above line of code
print(some_var)
#There is no output to the above line of code
print(type(some_var))
#Output: NoneType
You don't return anything at all and every function by default returns a None if nothing specified. For example:
def some_func():
print ("I print and return nothing")
some_var = some_func()
#Output : I print and return nothing
print(some_var)
#There is no output to the above line of code
print(type(some_var))
#Output: NoneType
Hope it helps.

Related

Using compile() with an expression with a function inside of it

Let's say I have something like this:
expr="
def something():
return True
something()"
somevar=compile(expr, "","eval")
This throws a syntax error on "def". I've also tried wrapping the compile() with an eval(), no use. I basically want the result of the function call. Is this possible with eval or compile? Is there any library that would achieve this? I want somevar to be False.
Thanks in advance
According to the docs:
The mode argument specifies what kind of code must be compiled; it can be 'exec' if source consists of a sequence of statements, 'eval' if it consists of a single expression, or 'single' if it consists of a single interactive statement
So there's a couple of things here:
You should use multi-line strings in Python (three """)
You shouldn't use "eval" but "exec"
The returned object is not executed. You have to explicitly call it once created.
With all that in mind:
expr = """
def something():
print('hi')
return "done"
something()
"""
somevar = compile(expr, "", "exec")
exec(somevar)
This does print "hi". However, that code itself doesn't return anything. You run the function something() which yes: returns "done" but after running something()? Where would you return the return?
One option, as explained in this other SO thread would be assigning the return value to what would become a sort of "global" variable:
expr = """
def something():
return "done"
retval = something()
"""
somevar = compile(expr, "", "exec")
exec(somevar)
print(retval)
I can't help but saying that this sort of convoluted coding, that runs code stored in strings is probably a bad idea. It's insecure, hard to track, debug, refactor... So if this is going to be used for something besides learning purposes... Well... I would invite you to try and think if there's another way of achieving what you want.

How to programmatically ensure that a function includes a return statement?

How can I validate that a function includes a return keyword? I frequently forget the return line, so I am worried that the users of my package will too when they provide a function-based input.
def appler():
a = "apple"
# `return` is missing
def bananer():
b = "banana"
return b
I could parse the actual code string of the function for a final line that includes "return" but that isn't very robust (it could be triggered by comments).
def validate_funk(funk):
if condition_to_check_that_it_contains_rtrn:
pass
else:
raise ValueError(f"Yikes - The function you provided not contain a `return` statement:\n\n{funk}")
>>> validate_funk(appler)
#triggers ValueError
>>> validate_funk(bananer)
# passes
EDIT: ideally without running the function.
What you actually care about is probably not the return statement itself, but that the function returns something of a certain type. This you can most easily accomplish by using type hints (PEP 484):
def appler() -> str:
a = "apple"
# `return` is missing
def bananer() -> str:
b = "banana"
return b
Now, running a static analysis tool like mypy or Pyre (or many others): will emit a warning about a wrong return type in function appler (expected str, got NoneType).
Look for sabik's answer for a more general answer. Writing (unit) tests is another good practice that catches many more issues and - if done well - is an invest in code maintainability.
A function without return statement returns None by default.
>>> def abc():
pass
>>> print(abc())
None
>>>
You can add a check using this:
def validate_func(function):
if function() == None:
raise ValueError("Yikes - Does not contain a `return` statement")
There are few cons though.
You have to execute the function
It wont work if you are returning None in a function
Not much practical but yea, that is one way. You can also get a list of local functions or a list of methods in a class and loop through them without having to check each function individually.
For the question as asked, the ast module will let you check that.
However, it doesn't seem very useful just by itself - as others have pointed out, a function without a return is valid (it returns None), and just because a function does have a return doesn't mean that it returns the correct value, or even any value (the return could be in an if statement).
There are a couple of standard ways of dealing with this:
Unit tests - separate code that calls your function with various combinations of inputs (possibly just one, possibly hundreds) and checks that the answers match the ones you calculated manually, or otherwise satisfy requirements.
A more general implementation of the idea of checking for a return statement is "lint", in the case of Python pylint; that looks through your code and checks for various patterns that look like they could be mistakes. A side benefit is that it already exists and it checks dozens of common patterns.
Another, different more general implementation is the mypy type checker; that not only checks that there's a return statement, but also that it returns the correct type, as annotated in the header of the function.
Typically, these would be used together with a "gated trunk" development process; manual changes to the main version are forbidden, and only changes which pass the tests, lint and/or mypy are accepted into the main version.
As others have mentioned, simply calling the function is not enough: a return statement might only be present in a conditional, and thus, specific input would need to be passed in order to execute the return statement. That, too, is not a good indicator of the presence of a return, since it could return None, causing greater ambiguity. Instead, the inspect and ast module can be used:
Test functions:
def appler():
a = "apple"
# `return` is missing
def bananer():
b = "banana"
return b
def deeper_test(val, val1):
if val and val1:
if val+val1 == 10:
return
def gen_func(v):
for i in v:
if isinstance(i, list):
yield from gen_func(i)
else:
yield i
inspect.getsource returns the entire source of the function as a string, which can then be passed to ast.parse. From there, the syntax tree can be recursively traversed, searching for the presence of a return statement:
import inspect, ast
fs = [appler, bananer, deeper_test, gen_func]
def has_return(f_obj):
return isinstance(f_obj, ast.Return) or \
any(has_return(i) for i in getattr(f_obj, 'body', []))
result = {i.__name__:has_return(ast.parse(inspect.getsource(i))) for i in fs}
Output:
{'appler': False, 'bananer': True, 'deeper_test': True, 'gen_func': False}
With a defined validate_funk:
def validate_funk(f):
if not has_return(ast.parse(inspect.getsource(f))):
raise ValueError(f"function '{f.__name__}' does not contain a `return` statement")
return True
Notes:
This solution does not require the test functions to be called.
The solution must be run in a file. If it is run in the shell, an OSError will be raised. For the file, see this Github Gist.
You can simplify return checking with a decorator:
def ensure_return(func):
def wrapper(*args, **kwargs):
res = func(*args, **kwargs)
if res is None:
raise ValueError(f'{func} did not return a value')
return res
return wrapper
#ensure_return
def appler():
a = "apple"
# `return` is missing
#ensure_return
def bananer():
b = "banana"
return b
then:
>>> appler()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in wrapper
ValueError: <function appler at 0x7f99d1a01160> did not return a value
>>> bananer()
'banana'

When is a function called/referred to and when is it being executed?

I'm relatively new to Python and I have a (I guess) pretty basic question on functions in Python.
I'm rewatching basics tutorials in order to really understand more of the structures and not just use them. I used some basic code from a tutorial and tried different simple variations and I don't fully understand the outcomes and when a function is being referred to, i.e. when its return value is being called for, and when it's being executed.
x=6
def example():
globx = x
print(globx)
globx+=5
print(globx)
example()
This defines the function and afterwards calls for it to be executed and as it's being executed it prints 6 and then prints 11, as expected.
Now:
x=6
def example():
globx = x
print(globx)
globx+=5
print(globx)
print(example())
I would have expected this to print "None" since print is looking for a return value of the function to print it but example() doesn't return a value. Instead 6, 11 and None are being printed. So I assume print(example()) calls for example()'s return value to print it but before also executes the function. (Please correct me if I got that wrong.).
Even when I'm just assigning the return value to a variable x = example() after the definition of the function, it will also execute the function and print 6 and then 11.
x=6
def example():
globx = x
print(globx)
globx+=5
print(globx)
x = example()
Is a function always being executed when it's written out? (Ecxcept in the def)
Is there a way to make use of a functions return value without it being fully executed?
For example if I had a more complex code and at some point I want to make use of a functions return value but don't want it to be run.
Thanks in advance!
What you say seems overall correct, even if it seems off what you expected.
Generally, you can see it as, when the function has parentheses at the end, i.e. example(), the function is executed.
Your last question is a bit vague, but you can stop executing the function at some point by using the return keyword inside the function. This makes sense in e.g. a function that performs some resource-intensive calculations, but occasionally there's a chance to take a shortcut.
As an example
def calculate_thing(shortcut = False):
if shortcut:
return 3
# Resource-intensive, time-consuming calculations go here
return result_of_calculations
Calling this function with calculate_thing(shortcut=True) will quickly return 3, because the function stops executing when we hit return 3. On the other hand, calling it by calculate_thing(shortcut=False) or calculate_thing() (False is the default value for shortcut) will make the function run for a while, doing some calculations, and then it returns whatever value was assigned to the variable result_of_calculations.
You are getting confused by what a function returns and what a function does.
In your case you have a function which has two print() statements. Those statements have nothing to do with the value that the function will return and will print their corresponding values on every invocation of the function example().
The return value of the function is defined using the return keyword and if it is not defined then it is None. Obviously the function needs to be executed in order to get it to return a value.
A function does something, it literally performs a function. If you want that function to show you results as it's doing its job, you can print() things. If you just want it to do its job and save the results for later, you return them to a variable that calls the function. You can do both!
def just_print(input):
print('Here is a function printing!', input)
just_print('cool!')
>> 'Here is a function printing!', 'cool!'
def return_value(input):
return 'Hello ' + input
# We can store the return for future use
save_return_val = return_value('Ari')
print(save_return_val)
>> 'Hello Ari'
# Just print it
print(return_value('Ari'))
>> 'Hello Ari'

What is the use of a return statement? [duplicate]

This question already has answers here:
What is the purpose of the return statement? How is it different from printing?
(15 answers)
Closed 4 years ago.
Let me clarify; Let us say that you have 2 functions in Python:
def helloNot():
a = print("Heya!")
helloNot()
Which will print out Heya! without a return statement.
But if we use a return statement in this function:
def hello():
a = print("Heya!")
return a
hello()
This will print out Heya! as well.
I have read and learned that a return statement returns the result back to the function but
doesn't the result get automatically returned by whatever result you have without a return statement inside a function?
In our case let's use the function helloNot() (our function without the return statement):
our variable a, which is a print statement returns the result to the function when we call it or am I missing something?
On a side note,
Why and when would we use return statements?
Is it a good habit to start using return statements?
Are there a lot more advantages to using return statements than there are disadvantages?
EDIT:
using the print statement was an example to better present my question. My question does NOT revolve around the print statement.
Thank you.
Normally, when you call a function, you want to get some result. For example, when I write s = sorted([3,2,1]), that call to sorted returns [1,2,3]. If it didn't, there wouldn't be any reason for me to ever call it.
A return statement is the way a function provides that result. There's no other way to do that, so it's not a matter of style; if your function has a useful result, you need a return statement.
In some cases, you're only calling a function for its side-effects, and there is no useful result. That's the case with print.
In Python, a function always has to have a value, even if there's nothing useful, but None is a general-purpose "no useful value" value, and leaving off a return statement means you automatically return None.
So, if your function has nothing useful to return, leave off a return statement. You could explicitly return None, but don't do that—use that when you want the reader to know you're specifically returning None as a useful value (e.g., if your function returns None on Tuesday, 3 on Friday, and 'Hello' every other day, it should use return None on Tuesdays, not nothing). When you're writing a "procedure", a function that's called only for side-effects and has no value, just don't return.
Now, let's look at your two examples:
def helloNot():
a = print("Heya!")
This prints out Heya!, and assigns the return value of print to a local variable, which you never use, then falls off the end of the function and implicitly returns None.
def hello():
a = print("Heya!")
return a
This prints out Heya!, and assigns the return value of print to a local variable, and then returns that local variable.
As it happens, print always returns None, so either way, you happen to be returning None. hello is probably a little clearer: it tells the reader that we're returning the (possibly useless) return value of print.
But a better way to write this function is:
def hi():
print("Heya!")
After all, we know that print never has anything useful to return. Even if you didn't know that, you know that you didn't have a use for whatever it might return. So, why store it, and why return it?
You should use return statements if you want to compute a value from a function and give it back to the caller.
For your example, if the goal of the function is just to print a fixed string, there's no good reason to return the return value of print.
If you don't return anything from a function, Python implicitly returns a None. print falls in this category.
In [804]: a = print('something')
something
In [806]: print(a)
None
Similarly with functions that the user defines
In [807]: def f():
...: print('this is f')
...:
In [808]: fa = f() # Note this is assigning the *return value* of f()
this is f
In [809]: print(fa)
None
What you are doing does not require a return statement, you're right but consider you want to calculate an average.
def calculateAverage(x, y, z):
avg = ((x + y + z)/3)
return avg
Now that you have declared a function that has the ability to take 3 variables and return the calculated average you can now call it from any function and not have to have bulky code.
a = calculateAverage(7, 5, 9)
print("Average is:" + a)
Which will print to screen "Average is: 7"
The power of functions and return values is that you are able to make your code more readable by means of placing a single call to a sophisticated function in your main logic, which means you now have less lines of code and it is more legible/maintainable in the longrun.
Hopefully this helps.

How to use a callback function in python?

I wonder how to correctly use python 2.7 callback functions.
I have some callback functions from Cherrypy auth examples in my code.
(These callbacks return a function that can evaluate to True or False, depending on the logged in user being in a group or not.)
I wonder if a callback is executed or not if I write a piece of code like this:
Given the definition from the library is:
def member_of(groupname):
def check():
if groupname == 'admin':
if cherrypy.request.login == 'joe':
return True
if cherrypy.request.login == 'toni':
return True
return False
return False
# .... (other groups checked in the same way)
return check # returns a callback function from my understanding?
How can I apply and execute the callback in my code?
If I put it like this:
if member_of('admin'):
do_something()
else:
do_something_else()
Will this execute the calllback and check for the admin group? Or will it find out if the value of "member_of" is a function definition and a function definition is probably always a "True" value (or maybe a False value) but both are wrong, because it needs to be executed
Can you enlighten me on this? How can I make sure a callback is executed? An how can I pass it around as it is?
In python, like in many other languages, a variable can also contain a function and you can pass them around like other variables that contain e.g. numbers or strings.
CherryPy's member_of function itself does return a function in your example.
I am explaining it in simple steps:
If you write member_of() it returns the result of the function member_of() which is the function with the name check in this case.
cb_function = member_of('admin')
At this point the variable cb_function holds the result of calling the function member_of, and in the last line member_of returns check, which was defined within the function member_of as another function!
You have to call the first result again, because you can and you have to treat it in almost the same way as a local function, that you defined in the current context, to get the final result, by doing something like:
my_result = cb_function()
And then you would continue and use the result. For example you could check its boolean value:
if my_result:
# do something
...
The 3 steps from above together can be written shorter:
cb_function = member_of('admin')
if cb_function():
# do something
...
Or even shorter:
if member_of('admin')():
# do something
...
At first it may appear a little strange in python to have the double ()(), but if you think about it for a while it makes sense.
If you execute it, it is plain simple.
member_of() will return method object check.
you have to execute to get result by doing something like if member_of('admin')():
or,
k=member_of('admin')
if k():
To do your task.

Categories

Resources