Wenn Sie eine Methode dekorieren, ist sie noch nicht an die Klasse gebunden und verfügt daher noch nicht über das Attribut im_class
. Ich suche nach einer Möglichkeit, die Informationen über die Klasse im Dekorateur zu erhalten. Ich habe es versucht:
import types
def decorator(method):
def set_signal(self, name, value):
print name
if name == 'im_class':
print "I got the class"
method.__setattr__ = types.MethodType(set_signal, method)
return method
class Test(object):
@decorator
def bar(self, foo):
print foo
Aber es druckt nichts.
Ich kann mir das vorstellen:
class Test(object):
@decorator(klass=Test)
def bar(self, foo):
print foo
Aber wenn ich es vermeiden kann, würde es meinen Tag machen.
3 Antworten
Meine strenge Antwort wäre: Es ist nicht möglich, da die Klasse noch nicht existiert, wenn der Dekorateur ausgeführt wird.
Die längere Antwort hängt von Ihren genauen Anforderungen ab. Wie ich geschrieben habe, können Sie nicht auf die Klasse zugreifen, wenn sie noch nicht existiert. Eine Lösung wäre, die dekorierte Methode zu markieren, die später "transformiert" werden soll. Verwenden Sie dann eine Metaklasse oder einen Klassendekorateur, um Ihre Änderungen anzuwenden, nachdem die Klasse erstellt wurde.
Eine andere Option beinhaltet etwas Magie. Suchen Sie nach der Implementierung der Methode implements
in zope.interfaces
. Es hat Zugriff auf die Informationen über die Klasse, die gerade analysiert wurde. Ich weiß nicht, ob es für Ihren Anwendungsfall ausreicht.
Verwenden Sie Methodendekoratoren, um den interessanten Methoden einige Markierungsattribute hinzuzufügen, und verwenden Sie eine Metaklasse, die die Methoden durchläuft, die Markierungsattribute findet und die Logik ausführt. Der Metaklassencode wird beim Erstellen der Klasse ausgeführt, sodass er auf die neu erstellte Klasse verweist.
class MyMeta(object):
def __new__(...):
...
cls = ...
... iterate over dir(cls), find methods having .is_decorated, act on them
return cls
def decorator(f):
f.is_decorated = True
return f
class MyBase(object):
__metaclass__ = MyMeta
class MyClass(MyBase):
@decorator
def bar(self, foo):
print foo
Wenn Sie sich darüber Sorgen machen, dass der Programmierer von MyClass
die Verwendung von MyBase
vergisst, können Sie die Metaklasse zwangsweise in decorator
setzen, indem Sie das globale Wörterbuch des Aufrufer-Stack-Frames ({{X3}) untersuchen. }).
Vielleicht möchten Sie einen Blick auf Deskriptoren werfen. Mit ihnen können Sie ein __get__
implementieren, das beim Zugriff auf ein Attribut verwendet wird, und können je nach Objekt und Typ verschiedene Dinge zurückgeben.
Verwandte Fragen
Verknüpfte Fragen
Neue Fragen
python
Python ist eine dynamisch typisierte Mehrzweck-Programmiersprache mit mehreren Paradigmen. Es wurde entwickelt, um schnell zu lernen, zu verstehen, zu verwenden und eine saubere und einheitliche Syntax durchzusetzen. Bitte beachten Sie, dass Python 2 ab dem 01.01.2020 offiziell nicht mehr unterstützt wird. Fügen Sie für versionenspezifische Python-Fragen das Tag [python-2.7] oder [python-3.x] hinzu. Wenn Sie eine Python-Variante (z. B. Jython, PyPy) oder eine Bibliothek (z. B. Pandas und NumPy) verwenden, fügen Sie diese bitte in die Tags ein.