shau-kote
вылетает с UnboundLocalError на первой строке f2(). Причём вылетает при попытке вызвать функцию f1()
эти срабатывают
>>> def f1():
... x = 0
... def f2():
... print(x)
... x = 1
... print(x)
... #f2()
...
>>> f1()
>>>
>>> def f1():
... x = 0
... def f2():
... nonlocal x
... print(x)
... x = 1
... print(x)
... f2()
...
>>> f1()
0
1
>>>
смотрим области у несрабатывающей
>>> def f1():
... x = 0
... def f2():
... print(globals(), locals())
... print(x)
... x = 1
... print(x)
... f2()
...
>>> f1()
{'__doc__': None, 'f1': <function f1 at 0x7f2eceb3ad40>, '__builtins__': <module 'builtins'>, '__loader__': <_frozen_importlib.SourceFileLoader object at 0x7f2eceacb810>, '__name__': '__main__', 'clear': <function clear at 0x7f2eceb3acb0>, '__package__': None, '__cached__': None} {}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in f1
File "<stdin>", line 5, in f2
UnboundLocalError: local variable 'x' referenced before assignment
>>>
во втором питоне - тоже не срабатывает
>>> def f1():
... x = 0
... def f2():
... print globals(), locals()
... print x
... x = 1
... print x
... f2()
...
>>> f1()
{'f1': <function f1 at 0x7f6a8871e938>, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'clear': <function clear at 0x7f6a8871e8c0>, '__name__': '__main__', '__doc__': None} {}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in f1
File "<stdin>", line 5, in f2
UnboundLocalError: local variable 'x' referenced before assignment
>>>
пример для C на питоне
напрямую не работает, потому что области по-другому сделаны (в C нет вложенных функций)
>>> x = 0
>>>
... def f1():
... def f2():
... print(globals(), locals())
... print(x)
... x = 1
... print(x)
... f2()
...
>>> f1()
{'__loader__': <_frozen_importlib.SourceFileLoader object at 0x7f70a5d5c810>, 'f1': <function f1 at 0x7f70a5dcbd40>, 'x': 0, '__package__': None, '__builtins__': <module 'builtins'>, '__doc__': None, '__name__': '__main__', 'clear': <function clear at 0x7f70a5dcbcb0>, '__cached__': None} {}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in f1
File "<stdin>", line 5, in f2
UnboundLocalError: local variable 'x' referenced before assignment
>>>
разделяем переменные и смотрим области
>>> x0 = 0
>>>
... def f1():
... x = 0
... def f2():
... print(globals(), locals())
... print(x0)
... x = 1
... print(x)
... print(globals(), locals())
... f2()
...
>>> f1()
{'__loader__': <_frozen_importlib.SourceFileLoader object at 0x7f70a5d5c810>, 'f1': <function f1 at 0x7f70a5d6f170>, 'x': 0, '__package__': None, '__builtins__': <module 'builtins'>, '__doc__': None, '__name__': '__main__', 'clear': <function clear at 0x7f70a5dcbcb0>, 'x0': 0, '__cached__': None} {}
0
1
{'__loader__': <_frozen_importlib.SourceFileLoader object at 0x7f70a5d5c810>, 'f1': <function f1 at 0x7f70a5d6f170>, 'x': 0, '__package__': None, '__builtins__': <module 'builtins'>, '__doc__': None, '__name__': '__main__', 'clear': <function clear at 0x7f70a5dcbcb0>, 'x0': 0, '__cached__': None} {'x': 1}
>>>
влияем на области с помощью присваивания
>>> def f1():
... x = 0
... def f2():
... print(globals(), locals())
... print(x)
... #x = 1
... print(x)
... f2()
...
>>> f1()
{'f1': <function f1 at 0x7f9a5aafed40>, '__package__': None, 'clear': <function clear at 0x7f9a5aafecb0>, '__doc__': None, '__loader__': <_frozen_importlib.SourceFileLoader object at 0x7f9a5aa8f810>, '__builtins__': <module 'builtins'>, '__name__': '__main__', '__cached__': None} {'x': 0}
0
0
>>>
вот из-за того, что есть присваивание и нет
nonlocal, он её считает локальной
а локальные переменные он ищет в локальной области
какое-то наследование локальной области есть ещё: видимо, когда у функции нет локальных переменных, то она наследует локальную область от внешней функции