Chciałbym stworzyć dekorator klas Python (*), który byłby w stanie płynnie zawrzeć wszystkie typy metod, jakie klasa może mieć: instancja, klasa i statyczne.Jak utworzyć dekorator klas Pythona, który jest w stanie objąć metody instancji, klasy i statyczne?
Jest to kod mam teraz, z częściami, które rozkładają to skomentował:
def wrapItUp(method):
def wrapped(*args, **kwargs):
print "This method call was wrapped!"
return method(*args, **kwargs)
return wrapped
dundersICareAbout = ["__init__", "__str__", "__repr__"]#, "__new__"]
def doICareAboutThisOne(cls, methodName):
return (callable(getattr(cls, methodName))
and (not (methodName.startswith("__") and methodName.endswith("__"))
or methodName in dundersICareAbout))
def classDeco(cls):
myCallables = ((aname, getattr(cls, aname)) for aname in dir(cls) if doICareAboutThisOne(cls, aname))
for name, call in myCallables:
print "*** Decorating: %s.%s(...)" % (cls.__name__, name)
setattr(cls, name, wrapItUp(call))
return cls
@classDeco
class SomeClass(object):
def instanceMethod(self, p):
print "instanceMethod: p =", p
@classmethod
def classMethod(cls, p):
print "classMethod: p =", p
@staticmethod
def staticMethod(p):
print "staticMethod: p =", p
instance = SomeClass()
instance.instanceMethod(1)
#SomeClass.classMethod(2)
#instance.classMethod(2)
#SomeClass.staticMethod(3)
#instance.staticMethod(3)
Mam dwie kwestie próbuje uczynić tę pracę:
- podczas iteracji nad wszystkim kalki, jak się dowiedzieć, czy jest to instancja, klasa czy typ statyczny?
- Jak zastąpić metodę odpowiednią owiniętą wersją, która jest poprawnie wywoływana dla każdego z tych przypadków?
Obecnie, ten kod generuje różne TypeError
sw zależności od tego, co skomentował fragment jest komentarzem, jak:
TypeError: unbound method wrapped() must be called with SomeClass instance as first argument (got int instance instead)
TypeError: classMethod() takes exactly 2 arguments (3 given)
(*): To samo problem jest znacznie prostszy, jeśli jesteś decorating the methods directly.
Fajnie będzie zobaczyć, jak różni deweloperzy radzą sobie z tym samym, skomplikowanym problemem. – wberry
@wberry: tak, już czytam bieżące odpowiedzi i zauważyłem, że trudno będzie wybrać "odpowiedni". – Chuim