2013-03-24 4 views
4

В Python 2.7, выполнив следующий код:Python глобальные и локальные переменные

def f(): 
    a = a + 1 

f() 

дает следующий результат:

Traceback (most recent call last): 
    File "test.py", line 4, in <module> 
    f() 
    File "test.py", line 2, in f 
    a = a + 1 
UnboundLocalError: local variable 'a' referenced before assignment 

Но если я изменить код ниже:

def f(): 
    a[0] = a[0] + 1 

f() 

Я получаю следующую ошибку:

Traceback (most recent call last): 
    File "test.py", line 4, in <module> 
    f() 
    File "test.py", line 2, in f 
    a[0] = a[0] + 1 
NameError: global name 'a' is not defined 

Почему Python с учетом a является локальной переменной, когда она является int, глобальная, когда list? В чем причина этого?

P.S .: Я экспериментировал после чтения this thread.

ответ

5

Ключ находится в документации на the assignment statement:

Assignment of an object to a single target is recursively defined as follows.

If the target is an identifier (name) (e. g. a = a + 1):

  • If the name does not occur in a global statement in the current code block: the name is bound to the object in the current local namespace.
  • Otherwise: the name is bound to the object in the current global namespace.

The name is rebound if it was already bound. This may cause the reference count for the object previously bound to the name to reach zero, causing the object to be deallocated and its destructor (if it has one) to be called.

...

If the target is a subscription (e. g. a[0] = a[0] + 1): The primary expression in the reference is evaluated. It should yield either a mutable sequence object (such as a list) or a mapping object (such as a dictionary). Next, the subscript expression is evaluated.

В f Python видит, что вы связывании какое-то значение до a, видит, что a не использовался в операторе global a в этой области и готовит локальную переменную. Затем он пытается оценить выражение a + 1, ищет переменную a и находит неинициализированную локальную переменную. В результате получается UnboundLocalError.

В f Python видит, что вы присваиваете какое-то значение для подписки переменной a. Он ищет эту переменную в локальном пространстве имен и не находит ее. Затем он просматривает нелокальные пространства имен (закрытий), пока не достигнет глобального пространства имен. Как только он не находит a в глобальном пространстве имен, он выдает NameError.

+0

Я думаю, что ошибка не имеет ничего общего с назначением в g. Я редактировал вопрос, удаляя несвязанные утверждения. – fossilet

+0

@fossilet - извиняюсь, что я принял ваш вопрос - я обновляю свой ответ, дайте мне знать, если это поможет. –

-1

Не могли бы вы попробовать сделать что-то вроде этого:

def f(a): 
    a += 1 
    print a 

def g(): 
    a = 3 
    f(a) 

g() 
Смежные вопросы