Но этот ответ говорит, что проблема связана с назначением x. Если это так, то печать должна работать нормально, не так ли?
Вы должны понимать порядок, в котором происходят события. Еще до того, как ваш код Python будет скомпилирован и выполнен, нечто, называемое парсером, считывает код Python и проверяет синтаксис. Еще одна вещь, которую делает синтаксический анализатор, — помечает переменные как локальные. Когда синтаксический анализатор видит присваивание в коде в локальной области видимости, переменная в левой части присваивания помечается как локальная. В этот момент еще ничего не скомпилировано, не говоря уже о выполнении, и, следовательно, никакого присваивания не происходит; переменная просто помечена как локальная переменная.
После завершения парсера код компилируется и выполняется. Когда выполнение достигает оператора печати:
def main():
x = 10 #<---x in enclosing scope
def f():
print x #<-----
x = x + 1 #<-- x marked as local variable inside the function f()
оператор печати выглядит так, как будто он должен продолжить и напечатать x в области enclosing («E» в процессе поиска LEGB). Однако, поскольку синтаксический анализатор ранее помечал x как локальную переменную внутри f(), python не выходит за пределы локальной области («L» в процессе поиска LEGB) для поиска x. Поскольку x не был назначен в локальной области во время выполнения «print x», python выдает ошибку.
Обратите внимание, что даже если код, в котором происходит присваивание, НИКОГДА не будет выполняться, синтаксический анализатор по-прежнему помечает переменную слева от присваивания как локальную переменную. Синтаксический анализатор понятия не имеет о том, как что-то будет выполняться, поэтому он слепо ищет синтаксические ошибки и локальные переменные в вашем файле — даже в коде, который никогда не может быть выполнен. Вот несколько примеров этого:
def dostuff ():
x = 10
def f():
print x
if False: #The body of the if will never execute...
a b c #...yet the parser finds a syntax error here
return f
f = dostuff()
f()
--output:--
File "1.py", line 8
a b c
^
SyntaxError: invalid syntax
Парсер делает то же самое при маркировке локальных переменных:
def dostuff ():
x = 10
def f():
print x
if False: #The body of the if will never execute...
x = 0 #..yet the parser marks x as a local variable
return f
f = dostuff()
f()
Теперь посмотрите, что происходит, когда вы выполняете эту последнюю программу:
Traceback (most recent call last):
File "1.py", line 11, in <module>
f()
File "1.py", line 4, in f
print x
UnboundLocalError: local variable 'x' referenced before assignment
Когда выполняется оператор print x, поскольку синтаксический анализатор пометил x как локальную переменную, поиск x останавливается в локальной области видимости.
Эта «функция» не уникальна для python — она встречается и в других языках.
Что касается примера массива, когда вы пишете:
x[0] = x[0] + 1
это говорит python искать массив с именем x и присваивать что-то его первому элементу. Поскольку в локальной области нет присваивания чему-либо с именем x, синтаксический анализатор не помечает x как локальную переменную.
person
7stud
schedule
09.05.2013