I have a for loop running in a script, and in that for loop there is a function, def OpenButton():, which triggers when a tkinter button is pressed (although this has nothing to do with tkinter). I need the name of the def script to have a different string at the end, every time the for loops runs.
Example: First loop: def OpenButtonString1(): but the second time it runs to be def OpenButtonString2(): (They would be actual strings, not def OpenButtonString increasing number ():, but I can't figure it out, since using exec('def OpenButton' + StringName + '():') doesn't actually detect the indented lines under as something part of the function.
What you need is a function that returns functions. The name of a function isn't really that important.
>>> def function_creator(foo):
... def dynamic_function():
... print(foo)
... return dynamic_function
...
>>> func1 = function_creator('Hello')
>>> func2 = function_creator('World')
>>> func1()
Hello
>>> func2()
World
You can store the functions just like any other variable, like putting them in a list or dictionary. Also, as you can see in my example, you can pass whatever information you need into your function creator and the function it creates can use the info upon being called.
Related
Suppose I wrote a function to create another function, say like:
def g(x):
#do stuff
def h(y):
return x*y
return h
my_func = g(10)
for i in range(100):
print(my_func(i))
In my for loop I am calling my_func a hundred times, however since I only call g once to create my_func I would expect that the #do stuff bit of my code will only run once at the beginning and not once every iteration of the loop.
Can anyone confirm that this is actually the case or will it run every single time inside the for loop? I couldn't find a satisfactory answer elsewhere.
Correct, if there was a line of code where #do stuff is, it would only run once in this example.
Tip: if you had replaced it with print("test") you could have checked this for yourself.
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'
I am trying to make a function's output behave as if it's my input. The goal is to make a new output from the old output.
I have some code that looks like this:
def func():
BLOCK OF CODE
func()
There is no return statement in the function and no parameters within the parenthesis.
When I type func() to call my function as shown above, I get the desired output, which is a bunch of printed statements. Now I want to do something with that output to get another output.
All I'm trying to do is effectively "pipe" the output of one function into the input of another function (or, if possible, not even worry about creating another function at all, and instead doing something more direct). I looked into Python 3 writing to a pipe
but it did not help me. I also tried defining another function and using the preceding function as a parameter, which did not work either:
def another_func(func):
print another_statement
another_func(func)
I also tried making a closure (which "kind" of worked because at least it printed the same thing that func() would print, but still not very encouraging):
def func():
def another_func():
print another_statement
BLOCK OF CODE
another_func()
Finally, I tried designing both a decorator and a nested function to accomplish this, but I have no parameters in my function, which really threw off my code (didn't print anything at all).
Any advice on how to manipulate a function's output like as if it is your input so that it's possible to create a new output?
You could achieve this by redirecting stdout using a decorator:
from StringIO import StringIO
import sys
def pipe(f):
def decorated(*args, **kwargs):
old,sys.stdout = sys.stdout,StringIO()
try:
result = f(*args, **kwargs)
output = sys.stdout.getvalue()
finally:
sys.stdout = old
return result, output
return decorated
You could then get the result, output pair from any decorated function, eg:
#pipe
def test(x):
print x
return 0
test(3) -> (0, '3\n')
However, I can't think of a good reason why you'd want to do this.
(Actually, that's not quite true; it is handy when writing unit tests for user IO, such as when testing student assignments in a software engineering course. I seriously doubt that that's what the OP is trying to do, though.)
Return the desired value(s) from the function - instead of printing the values on the console, return them as strings, numbers, lists or any other type that makes sense. Otherwise, how do you expect to "connect" the output of a function as the input to another, if there is no output to begin with?
Of course, printing on the console doesn't count as output unless you're planning to eventually use OS pipes or a similar mechanism to connect two programs on the console, but keep things simple! just use the function's return values and worry about pipes later if and only if that's necessary for your problem in particular.
After reading the comments: "connecting" two functions by printing on the console from one and reading from the console from the other would be a really bad idea in this case, first you have to grasp the way functions return values to each other, trust me on this one: you have to rethink your program! even though other answers (strictly speaking) answer your original question, that's absolutely not what you should do.
just for fun ... because OP asked for it
import StringIO
import sys
def func1():
for i in range(1,10):
print "some stuff %d"%i
def func2(func):
old_std = sys.stdout
sys.stdout = StringIO.StringIO()
try:
func()
return sys.stdout.getvalue().splitlines()
finally:
sys.stdout = old_std
print func2(func1)
You need to return a value from your function. This can be used to assign the value into another variable.
Say I define some function doubleThis that will double the input
def doubleThis(x):
print 'this is x :', x
return x * 2 # note the return keyword
Now I can call the function with 3, and it returns 6 as expected
>>> doubleThis(3)
this is x : 3
6
Now I have another function subtractOne that returns the input value, minus 1.
def subtractOne(i):
print 'this is i :', i
return i - 1
Now comes the answer to your question. Note that we can call the first function as the input to the second, due to the fact that it has a return value.
>>> subtractOne(doubleThis(3))
this is x : 3
this is i : 6
5
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).
I have a question that I am sure has been on the mind of every intermediate-level Python programmer at some point: that is, how to fix/prevent/avoid/work around those ever-so-persistent and equally frustrating NameErrors. I'm not talking about actual errors (like typos, etc.), but a bizarre problem that basically say a global name was not defined, when in reality it was defined further down. For whatever reason, Python seems to be extremely needy in this area: every single variable absolutely positively has to hast to be defined above and only above anything that refers to it (or so it seems).
For example:
condition = True
if condition == True:
doStuff()
def doStuff():
it_worked = True
Causes Python to give me this:
Traceback (most recent call last):
File "C:\Users\Owner\Desktop\Python projects\test7.py", line 4, in <module>
doStuff()
NameError: name 'doStuff' is not defined
However, the name WAS defined, just not where Python apparently wanted it. So for a cheesy little function like doStuff() it's no big deal; just cut and paste the function into an area that satisfies the system's requirement for a certain order. But when you try to actually design something with it it makes organizing code practically impossible (I've had to "un-organize" tons of code to accomodate this bug). I have never encountered this problem with any of the other languages I've written in, so it seems to be specific to Python... but anyway I've researched this in the docs and haven't found any solutions (or even potential leads to a possible solution) so I'd appreciate any tips, tricks, workarounds or other suggestions.
It may be as simple as learning a specific organizational structure (like some kind of "Pythonic" and very strategic approach to working around the bug), or maybe just use a lot of import statements so it'll be easier to organize those in a specific order that will keep the system from acting up...
Avoid writing code (other than declarations) at top-level, use a main() function in files meant to be executed directly:
def main():
condition = True
if condition:
do_stuff()
def do_stuff():
it_worked = True
if __name__ == '__main__':
main()
This way you only need to make sure that the if..main construct follows the main() function (e.g. place it at the end of the file), the rest can be in any order. The file will be fully parsed (and thus all the names defined in the module can be resolved) by the time main() is executed.
As a rule of thumb: For most cases define all your functions first and then use them later in your code.
It is just the way it is: every name has to be defined at the time it is used.
This is especially true at code being executed at top level:
func()
def func():
func2()
def func2():
print "OK"
func()
The first func() will fail, because it is not defined yet.
But if I call func() at the end, everything will be OK, although func2() is defined after func().
Why? Because at the time of calling, func2() exists.
In short, the code of func() says "Call whatever is defined as func2 at the time of calling".
In Python defining a function is an act which happens at runtime, not at compile time. During that act, the code compiled at compile time is assigned to the name of the function. This name then is a variable in the current scope. It can be overwritten later as any other variable can:
def f():
print 42
f() # will print 42
def f():
print 23
f() # will print 23
You can even assign functions like other values to variables:
def f():
print 42
g = 23
f() # will print 42
g # will print 23
f, g = g, f
f # will print 23
g() # will print 42
When you say that you didn't come across this in other languages, it's because the other languages you are referring to aren't interpreted as a script. Try similar things in bash for instance and you will find that things can be as in Python in other languages as well.
There are a few things to say about this:
If your code is so complex that you can't organize it in one file, think about using many files and import them into one smaller main file
I you put your function in a class it will work. example:
class test():
def __init__(self):
self.do_something()
def do_something(self):
print 'test'
As said in the comment from Volatility that is an characteristic of interpreted languages