This question already has answers here:
Why can't Python increment variable in closure?
(3 answers)
Read/Write Python Closures
(8 answers)
Closed 5 years ago.
When I run the code below:
def run():
test = False
def tester():
if not test:
print("test is false")
else:
print("test is true")
test = not test
tester()
run()
I get the error:
local variable 'test' referenced before assignment
I was under the impression that the child function would have access to the parent functions variables. After playing with this code a bit I've found that if I remove the assignment (test = not test) then everything works fine.
Why does having an assignment in the child function break this code? If I shouldn't have the assignment in the child function, what would be the best way to toggle the test flag? Should I just return a value from the child function and use that to toggle test?
Python 2 doesn't support assignments to variables closed over by a nested function. The usual workaround is to put the value in a mutable container (e.g., a one-element list). Python 3 offers the nonlocal keyword for this purpose.
Related
This question already has answers here:
How can I select a variable by (string) name?
(5 answers)
How do I create variable variables?
(17 answers)
Closed 2 years ago.
In unix shell script:
if I call
function_name "${!variable}" -> variable will replaced during the execution/runtime
is there something alternative exists in python? there are some other logic involved prior creating the variable. But I'm interested in {!variable} alternative.
You are looking for the eval function:
a = "there"
b = "a"
eval(b)
Yielding the output:
'there'
Of course, the eval function, while being a bit more verbose than the bash indirect variable reference, is also much more versatile, as you can have the indirectly referenced variable (b in this case), contain any python expression.
In python functions are 1st class objects. Which means you can pass them around just like any variable.
def print_this():
print('this')
def print_that():
print('that')
p1 = print_this
p2 = print_that
p1()
p2()
So you don't need to use eval.
This question already has answers here:
How to get local variables updated, when using the `exec` call?
(3 answers)
Setting variables with exec inside a function
(2 answers)
Closed 3 years ago.
I have a function with an unspecified number of input strings which are intended to be variable names. For example
def f(*args):
for arg in args:
exec('{} = 1'.format(arg))
return a
f('a', 'b')
When running the code, I recieve the following error
NameError: name 'a' is not defined
How do I assign local variables for the function which are to be manipulated or returned? The solution provided in this similar but different question requires creating the variables outside the function, i.e. adding them to the global namespace, but that is not what I want.
This question already has answers here:
Keep the lifespan of variable after multiple function calls?
(4 answers)
Closed 5 years ago.
Assuming:
def myfunc(x):
listv = []
listv.append(x)
is there a keyword to stop a variable (listv) from being reassigned?
Let's suppose that NRA is a keyword:
def myfunc(x):
NRA listv = []
listv.append(x)
...line will be read and not reassigned but the variable still active appending new values for every function call. I know about the GLOBAL variable, but I just want to know is the keyword exists!
Variables in functions are not supposed to be persistent between function calls. Because functions are meant to be reusable codes that can be called from different context in the program. So to your answer, NO! There's no keyword for making a variable declared in function persistent.
This question already has answers here:
Short description of the scoping rules?
(9 answers)
Closed 5 years ago.
In this code, why do a and b not get destroyed at the ends of their respective blocks?
flag = True
if flag:
a = 1
for i in range(2):
b = 2
print(a, b)
Instead, this code prints 1 2. Why does Python allow this? When can I rely on this behavior?
Read up on the scoping rules for Python. In short, a scope is started with a new module: function, method, class, etc. Mere control flow statements (e.g. if and for) do not start a new scope. The scope of a variable is from its firs definition to the end of that scope.
Since this example has only one scope, each variable is good from its first assignment to the end of the file.
Is that enough to clear up the problem?
This question already has answers here:
Can you explain closures (as they relate to Python)?
(13 answers)
Closed 6 years ago.
I am trying to understand the background of why the following works:
def part_string(items):
if len(items) == 1:
item = items[0]
def g(obj):
return obj[item]
else:
def g(obj):
return tuple(obj[item] for item in items)
return g
my_indexes = (2,1)
my_string = 'ABCDEFG'
function_instance = part_string(my_indexes)
print(function_instance(my_string))
# also works: print(part_string(my_indexes)(my_string))
how come I can pass my_string to function_instance object even though I already passed my_indexes attributes to part_string() when creating function_instance? why Python accepts my_string implicitly?
I guess it has something to do with the following, so more questions here:
what is obj in g(obj)? can this be something other e.g. g(stuff) (like with self which is just a convention)?
what if I want to pass 2 objects to function_instance? how do I refer to them in g(obj)?
Can You recommend some reading on this?
What you're encountering is a closure.
When you write part_string(my_indexes) you're creating a new function, and upon calling it, you use the old variables you gave to part_string together with the new variables given to function_instance.
You may name the inner function whatever you want, and there is no convention. (obj is used in here but it can be pie. There are no conventions for this except func for function closures (decorators).
If you wish to pass two variables to the function, you may define two variables to the g(obj) function:
def g(var1, var2):
...
Here's some more info regarding closures in python.