0

This is a weird situation I've been scratching my head about for an hour or so. I can't explain this error, can you? If v1 is None, the if v1 is not None: block doesn't get run, but v2 is already defined in the method definition, with default of None. Why is it when I pass v1 with a value, it works, but when using the default None, it makes the v2 unbound? If I change it so that the if v1 is not None: block is outside the method() it works, but not if it is inside. I don't understand this behavior. Thanks for any clarification you can give me.

>>> def test(v1=None, v2=None):
...     def method():
...         if v1 is not None:
...             v2 = 1
...         print v1
...         print v2
...     method()
...
>>> test()
None
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in test
  File "<stdin>", line 6, in method
UnboundLocalError: local variable 'v2' referenced before assignment
>>> test('test1', 'test2')
test1
1
>>> 
>>> def test(v1=None, v2=None):
...     if v1 is not None:
...         v2 = 1
...     def method():
...         print v1
...         print v2
...     method()
...
>>> test()
>>> def test(v1=None, v2=None):
...     if v1 is not None:
...         v2 = 1
...     def method():
...         print v1
...         print v2
...     method()
... 
>>> test()
None
None
>>> test('test1', 'test2')
test1
1
>>> 
Furbeenator
  • 8,106
  • 4
  • 46
  • 54
  • 1
    You're only confusing yourself by nesting functions. This is a standard problem with assigning to values outside the current scope - the inner `v2` in your first example isn't explicitly `global`/`nonlocal`, so it's not the same as the default argument you closed over. – jonrsharpe Feb 08 '17 at 23:54
  • So because the if statement is outside the nested function in the second example, python forces `v2` to be global, even though the code block is never run? I'm just confused why it prints `v1` but doesn't have `v2` bound. – Furbeenator Feb 09 '17 at 00:03
  • @jonrsharpe incorrect by a mile: http://stackoverflow.com/questions/4020419/why-arent-python-nested-functions-called-closures – the_constant Feb 09 '17 at 00:05
  • @Vincenzzzochi really constructive, thanks – jonrsharpe Feb 09 '17 at 00:09
  • Thank you both, I'll have to crack into the python guide for some more details on this. It is weird because the original code I used has several default arguments, all of which are available to the nested function, this is the only one that is not bound and also the only one involved with an if statement that modifies it, even though that if is not true. – Furbeenator Feb 09 '17 at 00:20
  • Please read the dupe and other questions relating to the same error message - it doesn't matter that the assignment doesn't get reached with your specific values, just that it's *reachable*. – jonrsharpe Feb 09 '17 at 09:42
  • I have and will a few more times. I just still don't understand why if I create three arguments two of them will be bound and one won't. The only difference being that one is involved in an if statement code block. That doesn't make sense to me. – Furbeenator Feb 09 '17 at 23:49

0 Answers0