Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Differences between class block and function block in python

Tags:

python

Code 1

x = 0

class Foo:
    print(x)
    x = 1
    print(x)

print(x)

Result 1

0
1
0

Code 2

x = 0

def foo():
    print(x)
    x = 1
    print(x)

foo()

Result 2

UnboundLocalError: local variable 'x' referenced before assignment.

Why can x reference objects from two namespaces in class block?
I don't understand why Code 1 not throw an UnboundLocalError.
Inconsistency between function and class bother me.


Update:

After reading the Python Docs several times, I still cannot understand the scoping rules.

The following are blocks: a module, a function body, and a class definition. ...[skip]...

If a name is bound in a block, it is a local variable of that block, unless declared as nonlocal. If a name is bound at the module level, it is a global variable. (The variables of the module code block are local and global.) If a variable is used in a code block but not defined there, it is a free variable.

If a name binding operation occurs anywhere within a code block, all uses of the name within the block are treated as references to the current block. This can lead to errors when a name is used within a block before it is bound. This rule is subtle. Python lacks declarations and allows name binding operations to occur anywhere within a code block. The local variables of a code block can be determined by scanning the entire text of the block for name binding operations.

like image 567
kev Avatar asked Oct 10 '12 00:10

kev


1 Answers

x = 0

class Foo:
    print(x)   # Foo.x isn't defined yet, so this is the global x
    x = 1      # This is referring to Foo.x
    print(x)   # So is this

print(x)

x = 0

def foo():
    print(x)   # Even though x is not defined yet, it's known to be local
               # because of the assignment
    x = 1      # This assignment means x is local for the whole function
    print(x)

foo()
like image 102
John La Rooy Avatar answered Sep 29 '22 13:09

John La Rooy