Example 1:
a=1
def b():
print a
a=2
print a
Example 2:
a=1
def b():
print a
if a==1:
a=2
print a
Example 1 works as expected, Example 2 fails with UnboundLocalError: local variable 'a' referenced before assignment on the first print a
Can someone explain why this happens ? Is it an error or a feature ?
The second example is not very useful but I don't see why it shouldn't work. I would expect function b to first print the global a then check if global a is 1. If that's true local a would be set to 2. Then either global a would be printed or local a depending on the value of global a. Well in the example global a is 1, so I would expect to see local a printed with the value of 2.
Example 3:
a=1
def b():
print a
works
Example 4:
a=1
def b():
print a
a=2
fails, as does Example 1 as correctly commented, I had actually only tested Example 3 and thought it was the same as Example 1.
Now I understand the ever so often repeated thing about the whole scope. It's completely new to me and I have fun with the following example (Ipython):
In [13]: a=1
In [14]: def b():
....: a=2
....: global a
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
....: print a
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
....:
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<ipython-input-14-4fe1c6cdc9d0>:3: SyntaxWarning: name 'a' is assigned to before global
declaration
global a
In [15]: b()
2
In [16]: print a
2
So the mechanism differs from declaring a function or things like that where I can only access the state after I have changed it.
Are there any other actions in python that work like this - travelling through time ?
To make the examples work globals() could be used:
Example 1 working:
a=1
def b():
print globals()["a"]
a=2
print a
Example 2 working:
a=1
def b():
global_a=globals()["a"]
print global_a
if global_a==1:
a=2
print a
Example 4 working:
a=1
def b():
print globals()["a"]
a=2
Python determines the scope of a name on the basis of assignment at parse time. If you assign to a name, it is local for the entire scope. You are assigning to a in b() so it is a local name, it is never seen as a global name.
You'll have to tell the parser to treat a as a global explicitly in such a case:
def b():
global a
print a
if a==1:
a=2
print a
Note that your first example fails with the exact same error; you are assigning in that version too, so it too raises UnboundLocalError:\
>>> a=1
>>> def b():
... print a
... a=2
... print a
...
>>> b()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in b
UnboundLocalError: local variable 'a' referenced before assignment
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