22 Stimmen

Selbstreferenzierende Klassendefinition in Python

Gibt es eine Möglichkeit, innerhalb der Klassendeklaration auf einen Klassennamen zu verweisen? Es folgt ein Beispiel:

class Plan(SiloBase):
    cost = DataField(int)
    start = DataField(System.DateTime)
    name = DataField(str)
    items = DataCollection(int)
    subPlan = ReferenceField(Plan)

Ich habe eine Metaklasse, die diese Informationen liest und tut einige Setup, und die Basisklasse implementiert einige gemeinsame speichern Zeug. Ich würde gerne in der Lage sein, rekursive Definitionen wie diese zu erstellen, aber bisher in meinem Experimentieren ich nicht in der Lage gewesen, den Effekt zu erhalten, die ich wünsche, in der Regel läuft in eine "Plan ist nicht definiert" Fehler. Ich verstehe, was passiert ist, der Name der Klasse ist nicht im Bereich innerhalb der Klasse.

0voto

spacether Punkte 1486

Man kann dies mit folgendem Code in Python3 erreichen. Wir verwenden cached_property, um den Player.enemyPlayer nur einmal auszuwerten und dann das zwischengespeicherte Ergebnis zurückzugeben. Da unser Wert aus einer Funktion stammt, wird er nicht ausgewertet, wenn die Klasse zum ersten Mal geladen wird.

class cached_property(object):
    # this caches the result of the function call for fn with no inputs
    # use this as a decorator on function methods that you want converted
    # into cached properties
    def __init__(self, fn):
        self._fn = fn

    def __set_name__(self, owner, name):
        # only works in python >= 3.6
        self.name = name
        self._cache_key = "_" + self.name

    def __get__(self, instance, cls=None):
        if self._cache_key in vars(self):
            return vars(self)[self._cache_key]
        else:
            result = self._fn()
            setattr(self, self._cache_key, result)
            return result

class Player:
    @cached_property
    def enemyPlayer():
        return Player

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X