Python – Referenzieren des Klassennamens aus dem Klassenkörper heraus
-
27-09-2020 - |
Frage
In Python möchte ich ein Klassenattribut, ein Wörterbuch, mit initialisierten Werten haben.Ich habe diesen Code geschrieben:
class MetaDataElement:
(MD_INVALID, MD_CATEGORY, MD_TAG) = range(3)
mapInitiator2Type = {'!':MetaDataElement.MD_CATEGORY,
'#':MetaDataElement.MD_TAG}
Aber wenn ich versuche, diesen Code auszuführen, erhalte ich eine Fehlermeldung mit „NameError:Name 'MetaDataElement' ist nicht definiert".Kannst du mir helfen?
Dank im Voraus.
Lösung
Sie können sich nicht darauf beziehen MetaDataElement
während es gebaut wird, da es noch nicht existiert.Daher,
class MetaDataElement:
(MD_INVALID, MD_CATEGORY, MD_TAG) = range(3)
mapInitiator2Type = {'!':MetaDataElement.MD_CATEGORY,
'#':MetaDataElement.MD_TAG}
scheitert, weil die Konstruktion von mapInitiator2Type
erfordert MetaDataElement
Eigenschaften haben, die es noch nicht hat.Sie können an Ihre Konstanten denken MD_INVALID
, usw.als Variablen, die für die Konstruktion Ihrer Klasse lokal sind.Aus diesem Grund funktioniert Folgendes, wie icktoofay schrieb:
class MetaDataElement:
(MD_INVALID, MD_CATEGORY, MD_TAG) = range(3)
mapInitiator2Type = {'!': MD_CATEGORY, # MD_CATEGORY is like a local variable!
'#': MD_TAG}
Sie können sich jedoch auf die Klasse beziehen MetaDataElement
in jedem noch nicht interpretierten Codeabschnitt, wie in
def method_of_MetaDataElement(self):
print MetaDataElement.MD_TAG
Du auch haben zu beziehen MetaDataElement
, hier, weil MD_TAG
ist keine Art lokale Variable wann method_of_MetaDataElement()
wird ausgeführt (MD_TAG
wurde erst beim Klassenaufbau als eine Art lokale Variable definiert).Sobald die Klasse MetaDataElement
geschaffen, MD_TAG
ist einfach ein Klassenattribut, weshalb method_of_MetaDataElement()
muss es als solches bezeichnen.
Andere Tipps
Zunächst einmal verwenden Sie Klassen im alten Stil.Sie sollten wahrscheinlich Klassen neuen Stils verwenden, etwa so:
class MetaDataElement(object):
...
Beachten Sie das (object)
.Wie auch immer, entfernen Sie einfach die MetaDataElement.
wenn auf die Klassenattribute Bezug genommen wird.So würde es aussehen, wenn das erledigt ist:
class MetaDataElement(object):
(MD_INVALID, MD_CATEGORY, MD_TAG) = range(3)
mapInitiator2Type = {'!': MD_CATEGORY,
'#': MD_TAG}