def do_something():
print 'doing something...'
def maybe_do_it(hesitant=False):
if hesitant:
do_something = lambda: 'did nothing'
result = do_something()
print result
maybe_do_it()
The result of this code is:
File "scope_test.py", line 10, in <module>
maybe_do_it()
File "scope_test.py", line 7, in maybe_do_it
result = do_something()
UnboundLocalError: local variable 'do_something' referenced before assignment
But this code prints "did something..." as expected:
def do_something():
print 'doing something...'
def maybe_do_it(hesitant=False):
result = do_something()
print result
maybe_do_it()
How did the function get overridden even though the condition inside the if statement never executed? This happens in Python 2.7 -- is it the same in Python 3?
Re: Using global variables in functions with if statements There are global and local variables. All variables declared in the first (global) namespace are global. All other variables (declared in a function) are local in the function.
Scope of a Variable in If Statement Unlike languages such as C, a Python variable is in scope for the whole of the function (or class, or module) where it appears, not just in the innermost "block". So, anything declared in an if block has the same scope as anything declared outside the block.
python allows creation of variables in an if... elif... else... clause, so that they can be used also outside the conditional block. This is also true for nested conditionals.
In general, a variable that is defined in a block is available in that block only. It is not accessible outside the block. Such a variable is called a local variable.
How did the function get overridden even though the condition inside the if statement never executed?
The decision whether the variable is local or global is made at compile time. If there is an assignment to a variable anywhere in the function, it's a local variable, no matter if the assignment is ever executed.
This happens in Python 2.7 -- is it the same in python 3?
Yes.
By the way, in Python 2, you can override this behavior by using exec
(not recommended):
def do_something():
print 'doing something...'
def maybe_do_it(hesitant=False):
if hesitant:
exec "do_something = lambda: 'did nothing'"
result = do_something()
print result
maybe_do_it(False) # doing something...
maybe_do_it(True) # did nothing
An exec
inside a function will, loosely speaking, postpone the decision whether to look up the variable globally or locally to execution time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With