Frage

Gibt es eine Möglichkeit zu sehen, was die Anwendung eines Python-Dekorators mit einer Funktion bewirkt hat, auf die ich sie angewendet habe.Zum Beispiel, wenn ich habe

class A(object):

   @property
   def something(self):
       return 0

Ich würde gerne sehen, wofür der Code ausgeführt wird something sieht eigentlich so aus.Gibt es eine Möglichkeit, dies zu tun?

War es hilfreich?

Lösung

Ein Dekorateur produziert keinen Code;ein Dekorateur ist wirklich nur syntaktischer Zucker:

@property
def something(self):
    return 42

wird wirklich interpretiert als:

def something(self):
    return 42
something = property(something)

beispielsweise.der Ausdruck nach dem @ sign wird ausgewertet, und das Ergebnis wird aufgerufen, wobei die Funktion oder Klasse nach dem Übergeben wird @ Linie.Was auch immer der Dekorateur dann zurückgibt ersetzt Originalobjekt.

Für Introspektionszwecke, die @ linie ist nicht behalten;sie müssten den Quellcode selbst analysieren, um vorhandene Dekoratoren zu entdecken.Ein Dekorateur ist nicht verpflichtet, ein neues Objekt zurückzugeben;Sie können das ursprüngliche Objekt unverändert zurückgeben und bei Selbstbeobachtung den Unterschied nicht erkennen.

Am besten kehren Sie dann zur Quelle des Dekorateurs zurück und lesen einfach den Code.Der property dekorator ist in C implementiert, aber die beschreibung howto enthält eine Python-Implementierung, die dasselbe tut:

class Property(object):
    "Emulate PyProperty_Type() in Objects/descrobject.c"

    def __init__(self, fget=None, fset=None, fdel=None, doc=None):
        self.fget = fget
        self.fset = fset
        self.fdel = fdel
        if doc is None and fget is not None:
            doc = fget.__doc__
        self.__doc__ = doc

    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        if self.fget is None:
            raise AttributeError("unreadable attribute")
        return self.fget(obj)

    def __set__(self, obj, value):
        if self.fset is None:
            raise AttributeError("can't set attribute")
        self.fset(obj, value)

    def __delete__(self, obj):
        if self.fdel is None:
            raise AttributeError("can't delete attribute")
        self.fdel(obj)

    def getter(self, fget):
        return type(self)(fget, self.fset, self.fdel, self.__doc__)

    def setter(self, fset):
        return type(self)(self.fget, fset, self.fdel, self.__doc__)

    def deleter(self, fdel):
        return type(self)(self.fget, self.fset, fdel, self.__doc__)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top