2017-07-19 6 views
1

Hallo, ich bin etwas verwirrt über die Festlegung von Variablen in Python. Bitte erklären Sie den Unterschied zwischen den folgenden Snips.UnboundLocalError: Lokale Variable, die vor der Zuweisung referenziert wurde, warum die LEGB-Regel in diesem Fall nicht angewendet wurde

i)

class Test(object): 
    a_var = 1 

    def a_func(self): 
     self.a_var = self.a_var + 1 
     print(self.a_var, '[ a_var inside a_func() ]') 


    if __name__=='__main__': 
    t=Test() 
    t.a_func() 

O/P: 2 [a_var innen a_func()]

class Test(object): 
    a_var = 1 

    def a_func(self): 
     a_var = a_var + 1 
     print(a_var, '[ a_var inside a_func() ]') 


if __name__=='__main__': 
    t=Test() 
    t.a_func() 

o/p: UnboundLocalError: lokale Variable 'a_var' vor der Zuweisung referenzierten

Warum wird die LEGB-Regel nicht im zweiten Fall angewendet, wenn sie keinen Wert von enclosedesope erhält, der Klasse ist. bitte erklären. Danke im Voraus.

Antwort

1

Dies mag seltsam (und es ist), aber Sie keinen Verschluss über class bekommen, es ist nur über def. Der Bereich "e nclosing", auf den in L E Bezug genommen wird, handelt nur von Funktionsdefinitionen; Klassenblöcke zählen hier nicht.

Dieses seltsame Verhalten ist ein Artefakt der Art und Weise, wie Python historisch Klassen hinzugefügt wurde. Der Klassenumfang ist kein wirklicher Bereich. Python hatte nicht immer Klassen, und der gruselige "Zwischenbereich" existiert nur während der Klassendefinition: intern wird der Code unter dem Klassenkörper mehr oder weniger einfach unter exec unter einem temporären Gültigkeitsbereich ausgeführt, wobei das Ergebnis der Klasse zugewiesen wird Name. Dies war ein sehr einfacher "bolt-on" Ansatz, um OOP in die Sprache zu bringen, und das ist auch der Grund, warum Python das explizite self Ding als eine beabsichtigte Sprachdesignwahl hat.

Um aus einer Klassenmethode innerhalb einer Methode auf den a_var zuzugreifen, müssen Sie den Attributzugriff entweder über self.a_var oder Test.a_var verwenden. Beides sollte funktionieren. Sie können auch während der Klassendefinition direkt auf Klassenebene zugreifen, da Sie sich jedoch noch im temporären Bereich befinden, der nur ein weiteres Beispiel für einen lokalen Zugriff ist (L EGB).

Dies ist dokumentiert (wenn auch nicht besonders deutlich) unter dem execution model Abschnitt.

Class definition blocks and arguments to exec() and eval() are special in the context of name resolution. A class definition is an executable statement that may use and define names. These references follow the normal rules for name resolution with an exception that unbound local variables are looked up in the global namespace. The namespace of the class definition becomes the attribute dictionary of the class. The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods – this includes comprehensions and generator expressions since they are implemented using a function scope.

+0

Dank jetzt bin ich klar, woher du diese Art von Informationen habe ich fand es nicht in einigen Büchern "Das mag seltsam erscheinen (und es ist), aber Sie bekommen keine Schließung über die Klasse , es ist nur über def. Der "umschließende" Bereich, auf den in LEGB Bezug genommen wird, spricht nur über Funktionsdefinitionen; Klassenblöcke zählen hier nicht. " Kannst du mir einen Link zu einigen guten Artikeln geben, wo ich ein klares Konzept bezüglich Klassen, Variablen und Zugriffsmethoden und trickreiche varible-Initialisierung innerhalb der Klasse bekommen kann. Danke – user3256451

+0

Ich habe eine Docs-Referenz hinzugefügt. – wim

Verwandte Themen