Python global and local variables

In Python 2.7, the following code is executed:

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

gives the following result:

 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 

But if I change the code below:

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

I get a different error:

 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 

Why is Python given a a local variable if it is int , global when list ? What is the reason for this?

PS: I experimented after reading this topic .

+4
source share
2 answers

The key is in the documentation of the assignment instruction :

Assigning an object to one 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 expression in the current block code: the name is bound to an object in the current local namespace.
  • Otherwise: the name is bound to an object in the current global namespace.

The name is returned if it is already associated. This can cause the reference counter for the object previously associated with the name to reach zero, as a result of which the object will be freed and its destructor (if any) to be called.

...

If the target is a subscription (for example, a[0] = a[0] + 1 ): the main expression in the link is evaluated. It should give either a variable sequence object (for example, a list) or a matching object (for example, a dictionary). Then the index expression is evaluated.

In f 1, Python sees that you are binding some value to a , sees that a not used in the global a statement in this area, and prepares a local variable. Then he tries to evaluate the expression a + 1 , looks at the variable a and finds an uninitialized local variable. This results in an UnboundLocalError .

In f 2, Python sees that you assign some value to the subscription of the variable a . He searches for this variable in the local namespace and does not find it. He then scans for non-local namespaces (closures) until he reaches the global namespace. When it does not find a in the global namespace, it throws a NameError .

+5
source

Could you try to do something like this:

 def f(a): a += 1 print a def g(): a = 3 f(a) g() 
-1
source

All Articles