Пример 1:
a=1
def b():
print a
a=2
print a
Пример 2:
a=1
def b():
print a
if a==1:
a=2
print a
Пример 1 работает, как и ожидалось, пример 2 завершается с ошибкой UnboundLocalError: ссылка на локальную переменную 'a' перед назначением при первом выводе a
Может кто-нибудь объяснить, почему это происходит? Это ошибка или особенность?
Второй пример не очень полезен, но я не понимаю, почему он не должен работать. Я ожидаю, что функция b сначала напечатает глобальный a, а затем проверит, равен ли глобальный a 1. Если это правда, локальному a будет присвоено значение 2. Затем будет напечатан либо глобальный a, либо локальный a в зависимости от значения глобального a. Что ж, в примере глобальный а равен 1, поэтому я ожидаю увидеть локальный а со значением 2.
Пример 3:
a=1
def b():
print a
работает
Пример 4:
a=1
def b():
print a
a=2
терпит неудачу, как и пример 1, как правильно прокомментировано, на самом деле я тестировал только пример 3 и думал, что он такой же, как пример 1.
Теперь я понимаю то, что так часто повторялось в отношении всего масштаба. Это совершенно новое для меня, и я получаю удовольствие от следующего примера (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
Таким образом, механизм отличается от объявления функции или подобных вещей, когда я могу получить доступ к состоянию только после того, как я его изменил.
Существуют ли какие-либо другие действия в питоне, которые работают так — путешествие во времени?
Чтобы примеры работали, можно использовать globals():
Пример 1 работает:
a=1
def b():
print globals()["a"]
a=2
print a
Пример 2 работает:
a=1
def b():
global_a=globals()["a"]
print global_a
if global_a==1:
a=2
print a
Пример 4 работает:
a=1
def b():
print globals()["a"]
a=2
UnboundLocalError
. - person Martijn Pieters   schedule 09.06.2014