2013-11-22 9 views
7

In Python (getestet am 2.7.6) sind alle Variablen statisch an einen Bereich zur Kompilierzeit gebunden. Dieser Prozess ist gut in http://www.python.org/dev/peps/pep-0227/ beschrieben und http://docs.python.org/2.7/reference/executionmodel.htmlWarum statische Bindung für Klasse und Funktion anders funktioniert?

Es wird ausdrücklich festgestellt, dass „Wenn ein Name Betrieb Bindung erfolgt einer beliebigen Stelle innerhalb eines Codeblocks, alle Verwendungen des Namens innerhalb des Blocks sind als Verweise auf die aktuelle behandelt Block."

Eine Funktion ein Codeblock so der folgenden Code ist mit fail weil x nach seiner Verwendung zugeordnet ist (so bei der Kompilierung wird es lokal definiert weil es irgendwo in der Funktion zugewiesen, aber bei der Ausführung Zeit, wird benutzt, bevor man gebunden wird).

x = 1 
def f(): 
    print x 
    x = 2 
    print x 

>>> f() 

Traceback (most recent call last): 
    File "<pyshell#46>", line 1, in <module> 
    f() 
    File "<pyshell#45>", line 2, in f 
    print x 
UnboundLocalError: local variable 'x' referenced before assignment 

Eine Klasse ist auch ein Codeblock, also sollten wir genau das gleiche Verhalten beobachten. Aber das beobachte ich nicht. in diesem Beispiel aussehen:

x = 1 
class C(): 
    y = x + 10 
    x = 2 
    def __init__(self): 
     print C.y 

>>> C.x 
2 
>>> C.y 
11  
>>> C() 
11 
<__main__.C instance at 0x00000000027CC9C8> 

Da die Klassendefinition ein Codeblock ist, jede Zuordnung in diesem Block sollte die Variable lokal machen. So sollte x lokal zu der Klasse C sein, also sollte y = x + 10 zu einem UnboundLocalError führen. Warum gibt es keinen solchen Fehler?

+0

Dieser Thread http://stackoverflow.com/questions/12810426/differences-between-class-block-and-function-block-in-python verweist auf das gleiche Problem, aber keine starke Erklärung gegeben wird. Das PEP-0227- und das Python-2.7-Ausführungsmodell unterscheiden nicht zwischen einem Funktionsblock oder einem Klassenblock. – user3022222

+0

Dies ist ein häufiges Problem mit dem Bereich. Beachten Sie den Unterschied in den Namespaces zwischen den folgenden: '' und ''. Der Unterschied ist der Namensraum '__main__'. – VooDooNOFX

+0

Dies ist auch sehr eng verwandt mit http://stackoverflow.com/questions/12810426/differences-between-class-block-and-function-block-in-python – VooDooNOFX

Antwort

3

Ja - es scheint, dass die Dokumentation eher irreführend ist. Eine Klassendefinition nicht funktioniert eigentlich ganz gleich wie andere normale Blöcke:

global_one = 0 

class A(object): 
    x = global_one + 10 
    global_one = 100 
    y = global_one + 20 
    del global_one 
    z = global_one + 30 

a = A() 
print a.x, a.y, a.z, global_one 

Ergebnisse in: 10, 120, 30, 0

wenn Sie die gleiche Sache mit einer Funktion versuchen, erhalten Sie eine UnboundLocalError auf Ihrem ersten Zugriff auf global_one.

Der Grund dafür ist, dass Klassendefinitionen wie normal Zugriff auf den übergeordneten Bereich haben. Alle Namenszuweisungen ändern jedoch keinen lokalen Bereich, sondern werden tatsächlich im Datenattributwörterbuch der Klasse erfasst. Es gibt Hinweise in der Dokumentation, aber es ist sicherlich nicht offensichtlich.

Verwandte Themen