Python-Subklassenzugriff auf die Klassenvariable von Parent
War ich überrascht zu erfahren, dass eine Klasse, variable der Unterklasse keinen Zugriff auf eine Klassen-variable der Eltern, ohne speziell die Angabe der Klasse name der Eltern:
>>> class A(object):
... x = 0
...
>>> class B(A):
... y = x+1
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in B
NameError: name 'x' is not defined
>>> class B(A):
... y = A.x + 1
...
>>> B.x
0
>>> B.y
1
Warum ist es, dass in der Definition B. y habe ich zu verweisen auf A. x und nicht nur x? Dies ist entgegen meiner intuition von Instanz-Variablen, und da kann ich beziehen sich auf B. x nach B definiert ist.
InformationsquelleAutor der Frage Jeff O'Neill | 2010-09-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
In Python, der Körper einer Klasse ausgeführt wird, in seinem eigenen namespace, bevor die Klasse wird erstellt (nach denen die Mitglieder des namespace werden die Mitglieder der Klasse). Also, wenn der Dolmetscher erreicht y = x+1, Klasse B existiert noch nicht an diesem Punkt und hat daher kein Elternteil.
Weitere details finden Sie unter http://docs.python.org/reference/compound_stmts.html#class-definitions
InformationsquelleAutor der Antwort Nathan Davis
Python ' s scoping-Regeln für barenames sind sehr einfach und unkompliziert: lokale namespace ersten, dann (wenn überhaupt) äußere Funktionen, in denen die aktuelle geschachtelt ist, dann globals schließlich gebaut-ins. Das ist alles, was jemals geschieht, wenn ein barename nachgeschlagen, und es gibt keine Notwendigkeit zu merken oder gelten keine komplizierten Regeln (es gibt auch keine Notwendigkeit für einen Python-compiler zu erzwingen komplizierter Regeln).
Jeder Zeit Sie möchten eine andere lookup, werden Sie mit einem qualifizierte name, nicht ein nackten Namen. Qualifizierte Namen sind weit mehr mächtig, weil die Suche kann immer delegiert werden, um die Objekte, deren Attribute können abgefragt werden, und diese object implementieren kann, was auch immer nachschlagen-Regeln, die Sie benötigen. Insbesondere in einer Instanz-Methode innerhalb einer Klasse
self.x
ist die Art zu Fragen, dieself
Objekt nachschlagen Attribut name'x'
- und in diesem lookup-es delegieren können Klassen, einschließlich der Umsetzung des Konzepts der Vererbung (und die mehrfache Vererbung method resolution order, und so weiter).Den Körper einer Klasse sind (im Gegensatz zu den Körpern der Methoden in einer Klasse definiert) wird als Teil der
class
Anweisung, vor das class-Objekt erstellt wird, oder in seinen Namen gebunden ist (insbesondere, bevor Sie eine der Grundlagen definiert wurden als Basen-obwohl dieses Letzte detail, kann niemals eine Rolle spielen, wenn sich auf barenames, sowieso!-).So, in deinem Beispiel, in der Klasse
B
barenamex
gesucht wird, die mit der universellen Regeln-ist es ein name, der lokal gebunden? Wenn Nein, ist es gebunden in der äußeren Funktion, in der dieser Bereich verschachtelt ist? Wenn Nein, ist es gebunden, wie eine Globale oder? Wenn keine der oben genannten, mit der barename in Frage, die natürlich bewirkt, dass ein name-error-Ausnahme ausgelöst.Da Sie möchten eine andere lookup-Sequenz als die barename lookup-Regeln allgemein durchzusetzen, dann ist klar, müssen Sie einen qualifizierten Namen, nicht eine barename; und ein Augenblick nachdenken, wird deutlich, dass das "eine offensichtliche Wahl" für einen qualifizierten Namen verwenden, für Ihre Zwecke hat
A.x
-- da das ist, wo Sie wollen es nachgeschlagen werden (die Grundlagen wurden nicht verzeichnet noch an diesem Punkt, nachdem alle... es wird die Metaklasse, normalerweisetype
das tun wird der Basen-Bindung, die als Teil Ihrer Arbeit, wenn es aufgerufen wird nach der Rumpf der Klasse ist fertig ausführen!-).Manche Menschen sind so sehr an anderen "magischen" Regeln für die Suche barenames, dass Sie einfach nicht ausstehen kann dieser Aspekt von Python (ursprünglich inspiriert, glaube ich, von Modula-3, eine wenig bekannte Sprache ist, der sehr gut als in-Theoretiker " - Kreise;-) -- schreiben zu müssen
self.x
eine Methode, um anzugeben, dassx
muss gewartet werden bis aufself
anstatt mit den universal barename Regeln, zum Beispiel, treibt solche Leute bekloppt.Mir, ich Liebe die Einfachheit und Universalität der barename lookup-Regeln, und ich Liebe mit qualifizierten Namen statt barenames jeder Zeit ich will alle andere form der lookup... aber dann, es ist kein Geheimnis, dass ich bin verliebt in Python (ich habe meine eigene schimpft -- z.B.
global x
als eine Aussage immer macht meine Haut zu kriechen, wo ich würde viel lieber schreibenglobal.x
d.h., habenglobal
eine built-in-name für "die aktuell ausgeführten Modul"... ich tun Liebe qualifizierte Namen!-), ist es?-)InformationsquelleAutor der Antwort Alex Martelli