3
# coding: utf-8

def func():
    print 'x is', x
    #x = 2   #if I add this line, there will be an error, why?
    print 'Changed local x to', x
x = 50
func()
print 'Value of x is', x 
  1. I don't add the global x in func function, but it can still find x is 50, why?
  2. When I add the x=2 line in the func function, there will be an error (UnboundLocalError: local variable 'x' referenced before assignment), why?
BenMorel
  • 34,448
  • 50
  • 182
  • 322
Tanky Woo
  • 4,906
  • 9
  • 44
  • 75

3 Answers3

5

The trick here is that local names are detected statically:

  • As long as the name x is not assigned in the function, references to x resolve to the the global scope
  • If the name x is assigned anywhere in the function, Python assumes that x is thus a local name everywhere in the function. As a consequence, the first line becomes an error because local name x is used before being assigned.

In other words: assigned name is treated as local everywhere in the function, not just after the point of assignment.

icecrime
  • 74,451
  • 13
  • 99
  • 111
4

The global keyword is required only to write to globals.

There is an error because assigning to a variable which is not declared global creates a local variable of that name. You refer to x in that scope before it is assigned to, so you are attempting to read a local variable which has not yet been assigned.

Marcin
  • 48,559
  • 18
  • 128
  • 201
3

Python uses fairly typical variable scoping. Non-local variables are visible within a function.

You only need global keyword if you want to assign to a variable within global scope. Also you have to note the difference between global and outer scope. Consider implications:

x = 'global'
def f():
    x = 'local in f'
    def g():
        global x 
        x = 'assigned in g'
    g()
    print x

Upon execution of f() above code will print local in f, while x in global scope is set to 'assigned in g'.


As of Python 3, there is also nonlocal keyword, which allows you assigning to variable from outer scope.

x = 'global'
def f():
    x = 'local in f'
    def g():
        nonlocal x 
        x = 'assigned in g'
    return g
    print(x)

Upon execution of f() above code will print 'assigned in g(which is the value ofxin local scope off()), while value ofx` in global scope remains untouched.

It's also worth to note, that Python uses lexical (static) scoping, thus following code does not modify the x in the global scope:

x = 'global'
def f():
    x = 'local in f'
    def g():
        nonlocal x 
        x = 'assigned in g'
    return g
g = f()
g()
vartec
  • 131,205
  • 36
  • 218
  • 244
  • 1
    If you want to discuss the technical merits of something, do it constructively and maturely. Don't get into kiddish name-calling and fighting. Thanks. – BoltClock Apr 13 '12 at 11:55
  • @BoltClock'saUnicorn I don't see the disrespect you mention on this answer. oh..wait (checks English dictionary for `typical` ) ah .. tehre it is - it looks like this word has a negative cognation in English it does not get in other languages - Vartec, being a non-native speaker probably was not aware of that. """ 1. being or serving as a representative example of a particular type; characteristic the painting is a typical Rembrandt 2. considered to be an example of some undesirable trait that is typical of you!"""}(collins dict) - around the World, the first meaning is more spread) – jsbueno Apr 13 '12 at 13:17
  • @jsbueno: Well, it wasn't really an issue with the answer... it was something else. – BoltClock Apr 13 '12 at 13:20