I have been working at learning Python over the last week and it has been going really well, however I have now been introduced to custom functions and I sort of hit a wall. While I understand the basics of it, such as:
def helloworld():
print("Hello World!")
helloworld()
I know this will print "Hello World!".
However, when it comes to getting information from one function to another, I find that confusing. ie: function1 and function2 have to work together to perform a task. Also, when to use the return command.
Lastly, when I have a list or a dictionary inside of a function. I'll make something up just as an example.
def my_function():
my_dict = {"Key1":Value1,
"Key2":Value2,
"Key3":Value3,
"Key4":Value4,}
How would I access the key/value and be able to change them from outside of the function? ie: If I had a program that let you input/output player stats or a character attributes in a video game.
I understand bits and pieces of this, it just confuses me when they have different functions calling on each other.
Also, since this was my first encounter with the custom functions. Is this really ambitious to pursue and this could be the reason for all of my confusion? Since this is the most complex program I have seen yet.
Functions in python can be both, a regular procedure and a function with a return value. Actually, every Python's function will return a value, which might be None.
If a return statement is not present, then your function will be executed completely and leave normally following the code flow, yielding None as a return value.
def foo():
pass
foo() == None
>>> True
If you have a return statement inside your function. The return value will be the return value of the expression following it. For example you may have return None and you'll be explicitly returning None. You can also have return without anything else and there you'll be implicitly returning None, or, you can have return 3 and you'll be returning value 3. This may grow in complexity.
def foo():
print('hello')
return
print('world')
foo()
>>>'hello'
def add(a,b):
return a + b
add(3,4)
>>>7
If you want a dictionary (or any object) you created inside a function, just return it:
def my_function():
my_dict = {"Key1":Value1,
"Key2":Value2,
"Key3":Value3,
"Key4":Value4,}
return my_dict
d = my_function()
d['Key1']
>>> Value1
Those are the basics of function calling. There's even more. There are functions that return functions (also treated as decorators. You can even return multiple values (not really, you'll be just returning a tuple) and a lot a fun stuff :)
def two_values():
return 3,4
a,b = two_values()
print(a)
>>>3
print(b)
>>>4
Hope this helps!
The primary way to pass information between functions is with arguments and return values. Functions can't see each other's variables. You might think that after
def my_function():
my_dict = {"Key1":Value1,
"Key2":Value2,
"Key3":Value3,
"Key4":Value4,}
my_function()
my_dict would have a value that other functions would be able to see, but it turns out that's a really brittle way to design a language. Every time you call my_function, my_dict would lose its old value, even if you were still using it. Also, you'd have to know all the names used by every function in the system when picking the names to use when writing a new function, and the whole thing would rapidly become unmanageable. Python doesn't work that way; I can't think of any languages that do.
Instead, if a function needs to make information available to its caller, return the thing its caller needs to see:
def my_function():
return {"Key1":"Value1",
"Key2":"Value2",
"Key3":"Value3",
"Key4":"Value4",}
print(my_function()['Key1']) # Prints Value1
Note that a function ends when its execution hits a return statement (even if it's in the middle of a loop); you can't execute one return now, one return later, keep going, and return two things when you hit the end of the function. If you want to do that, keep a list of things you want to return and return the list when you're done.
You send information into and out of functions with arguments and return values, respectively. This function, for example:
def square(number):
"""Return the square of a number."""
return number * number
... recieves information through the number argument, and sends information back with the return ... statement. You can use it like this:
>>> x = square(7)
>>> print(x)
49
As you can see, we passed the value 7 to the function, and it returned the value 49 (which we stored in the variable x).
Now, lets say we have another function:
def halve(number):
"""Return half of a number."""
return number / 2.0
We can send information between two functions in a couple of different ways.
Use a temporary variable:
>>> tmp = square(6)
>>> halve(tmp)
18.0
use the first function directly as an argument to the second:
>>> halve(square(8))
32.0
Which of those you use will depend partly on personal taste, and partly on how complicated the thing you're trying to do is.
Even though they have the same name, the number variables inside square() and halve() are completely separate from each other, and they're invisible outside those functions:
>>> number
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'number' is not defined
So, it's actually impossible to "see" the variable my_dict in your example function. What you would normally do is something like this:
def my_function(my_dict):
# do something with my_dict
return my_dict
... and define my_dict outside the function.
(It's actually a little bit more complicated than that - dict objects are mutable (which just means they can change), so often you don't actually need to return them. However, for the time being it's probably best to get used to returning everything, just to be safe).
Related
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'
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.
I have function like this one:
def get_list_of_movies(table):
#some code here
print(a_list)
return a_list
Reason why I want to use print and return is that I'm using this function in many places. So after calling this function from menu I want to get printed list of content.
This same function I'm using in another function - just to get list. Problem is - when I call this function it prints list as well.
Question: How to prevent function from executing print line when its used in another function just to get list?
This is part of exercise so I can't define more functions / split this or soo - I'm kind of limited to this one function.
Edit: Thank you for all answers! I'm just beginner but you showed me ways in python(programming in general) that I never thought of! Using second parameter (boolin) is very cleaver. I do learn here a lot!
Add a separate argument with a default value of None to control the printing. Pass
def get_list_of_movies(table, printIt=False):
...
if printIt:
print(a_list)
return a_list
...
movies = get_list_of_movies(table, printIt=True)
Another approach is to pass print itself as the argument, where the default value is a no-op:
def get_list_of_movies(table, printer=lambda *args: None):
...
printer(a_list)
return a_list
...
movies = get_list_of_movies(table, printer=print)
This opens the door to being able to customize exactly how the result is print; you are effectively adding an arbitrary callback to be performed on the return value, which admittedly can be handled with a custom pass-through function as well:
def print_it_first(x):
print(x)
return x
movies = print_it_first(get_list_of_movies(table))
This doesn't require any special treatment of get_list_of_movies itself, so is probably preferable from a design standpoint.
A completely different approach is to always print the list, but control where it gets printed to:
def get_list_of_movies(table, print_to=os.devnull):
...
print(a_list, file=location)
return a_list
movies = get_list_of_movies(table, print_to=sys.stdout)
The print_to argument can be any file-like object, with the default ensuring no output is written anywhere.
I've heard that python functions are objects, similar to lists or dictionaries, etc. However, what would be a similar way of performing this type of action with a function?
# Assigning empty list to 'a'
a = list()
# Assigning empty function to 'a'
a = lambda: pass
# ???
How would you do this? Further, is it necessary or proper?
Here is the sense in which I would like to use it for better context:
I have a QListWidget for selecting items which are associated with keys in a dictionary. The values in this dictionary are also dictionaries, which hold certain properties of the items, which I can add. These certain properties are stored as keys, and the values in them are initialized or updated by calling different functions. So, I'm storing a variable in the window which gets updated when a button is pressed to tell this script which property to update.
As you can see, I would like to store the function to map to the data using the correct function based on the situation.
# Get selection from the list
name = selected_item
# Initialize an empty function
f = lambda: pass
# Use property that is being added now, which was updated by the specific button that was pushed
property_list = items[name][self.property_currently_being_added]
if self.property_currently_being_added == "prop1":
f = make_property1()
elif self.property_currently_being_added == "prop2":
f = make_property2()
elif self.property_currently_being_added == "prop3":
f = make_property3()
elif self.property_currently_being_added == "prop4":
f = make_property4()
# map the certain function to the data which was retrieved earlier
added_property = map(f, data)
property_list.append(added_property)
First, the reason this doesn't work:
a = lamdba: pass
… is that lambda only allows an expression, and defines a function that returns the value of the expression. Since pass is a statement, not an expression, this is illegal.
However, this works just fine:
a = lambda: None
In Python, a function that falls off the end without a return statement always returns None. So, these are equivalent:
def a(): return None
def a(): pass
However, I don't see why you want to write this as a lambda and an assignment anyway; the def is shorter, and more readable, and gives you an introspectable function object with a nice name (a instead of <lambda>), and so on. The only reasons to ever use lambda are when you don't want to give the function a name, or when you need to define the function inside an expression. Obviously neither of those are true, because you use the lambda directly inside an assignment statement. So, just use def.
Meanwhile, this is in a sense an "empty function", or at least as empty as possible (as you can see by, e.g., calling dis.dis(a), it still takes two bytecodes to do nothing but fall off the end and return None), but it's not useful for your case. You don't want an "empty function". If you try passing your a to map, you're just going to get a TypeError, because you're trying to call a function of no arguments with one argument. (Because that's what map does.)
What you might want is an identity function, which just returns its argument as-is. Like this:
def a(x): return x
But I'm not sure that's what you want. Did you want to append data as-is in that case? Or did you want to do something different, like return early, or raise an exception, or not append anything, or …?
Finally, I don't see why you want a function at all. Why not just not call map if you have nothing to map? You have a perfectly good else clause that already catches that case (especially handy if what you want to do is return early or raise…). Or, if you prefer, you can start with f = None, and then use an if f: do decide whether to map or not. Or, if you really want:
added_property = [f(element) if f else element for element in data]
… or …
added_property = map(f, data) if f else data
As one last note, instead of a long if/elif chain that repeats the same thing over and over again, you might want a dict:
propfuncs = {'prop1': make_property1(),
'prop2': make_property2(),
'prop3': make_property3(),
'prop4': make_property4()}
Then, all that cruft turns into these two lines:
f = propfuncs.get(self.property_currently_being_added)
added_property = map(f, data) if f else data
Or course an even better design might be to replace all those make_propertyN functions with a single function that you call as make_property(1) or make_property('prop1')… but without seeing what they actually do, I can't be sure of that.
For completeness and since the title is "empty function object in python", more general case is an empty function object that takes any number of parameters, so you can use it in any callback. It's this one:
callback = lambda *_, **__: None
Explanation is here: http://echochamber.me/viewtopic.php?t=64825
I am surprised to learn that you can even do...
def a(): "This is a test"
a()
this feels so much like you're looking for a Nothing functor, I am guessing that if you had knowledge of Monads you wouldn't even need an empty function , as inspiration PyMonad has a nice Nothing implementation, I usually like to create my own, but it's a good starting point.
I'm wondering if anyone can think up a way to check if a function needs to return a meaningful value in Python. That is, to check whether the return value will be used for anything. I'm guessing the answer is no, and it is better to restructure my program flow. The function in question pulls its return values from a network socket. If the return value is not going to get used, I don't want to waste the resources fetching the result.
I tried already to use tracebacks to discover the calling line, but that didn't work. Here's an example of what I had in mind:
>>> def func():
... print should_return()
...
>>> func()
False
>>> ret = func()
True
The function "knows" that its return value is being assigned.
Here is my current workaround:
>>> def func(**kwargs):
... should_return = kwargs.pop('_wait', False)
... print should_return
...
>>> func()
False
>>> ret = func(_wait=True)
True
The very second line of the body of import this says it all: "explicit is better than implicit". In this case, if you provide an optional argument, the code will be more obvious (and thus easier to understand), simpler, faster and safer. Keep it as a separate argument with a name like wait.
While with difficulty you could implement it magically, it would be nasty code, prone to breaking in new versions of Python and not obvious. Avoid that route; there lieth the path unto madness.
All functions return a value when they complete.
If you're asking if they should return at all, then you are actually asking about The Halting Problem
One approach might be to return an object with a __del__ method that relies on the garbage collector removing the unused value some time in the future.
Note that it won't happen immediately; it might not even happen at all :)
You might consider returning a future, or 'promise'. That is, return another function that, when executed, performs the necessary work to actually determine the result. I seem to be thinking that you want lazy evaluation, which is "evaluate only what you need" (more or less), rather than your question, which confusingly asks: "Evaluate only if it returns a value, which might be needed".
i have some code that kinda works using inspect module, but it might be prone to break like others mention.
inspect.stack()[1].frame.f_code.co_names[-1]
will be holding the function name when user didn't assign return value to anything, when user assign to var with name XXX, this var will hold XXX. Code comparing this vs the function name to decide whether user assign the return value to any var
import inspect
def func():
tmp = inspect.stack()[1].frame.f_code.co_names[-1]
should_return = tmp != 'func'
print("execute") # execute something
# if should_return False, end here without fetching result
if should_return:
print("fetching result, user assign to {}".format(tmp))
# fetching result and return the result here
>>> func()
execute
>>>
>>> xxx=func()
execute
fetching result, user assign to xxx
>>>
All functions in Python always return. If you don't explicitly return, functions return None.
===========
def func():
while True:
pass
This function does not return.
There is no way of determining if an arbitrary function will return. If you can, you have solved the Turing problem.