/ / Ozdobte triedu v Pythone tým, že definujete dekoráciu ako trieda - python, dekoratér

Zdobenie triedy v Pythone definovaním dekoratéra ako triedy - pythonu, dekoratéra

Čo je jednoduchý príklad zdobenia triedy definovaním dekoratéra ako triedy?

Snažím sa dosiahnuť to, čo bolo implementované v Pythone 2.6 PEP 3129 okrem použitia tried nefunguje, ako vysvetľuje Bruce Eckel tu.

Nasledujúce práce:

class Decorator(object):
def __init__(self, arg):
self.arg = arg

def __call__(self, cls):
def wrappedClass(*args):
return cls(*args)
return type("TestClass", (cls,), dict(newMethod=self.newMethod, classattr=self.arg))

def newMethod(self, value):
return value * 2

@Decorator("decorated class")
class TestClass(object):
def __init__(self):
self.name = "TestClass"
print "init %s"%self.name

def TestMethodInTestClass(self):
print "test method in test class"

def newMethod(self, value):
return value * 3

Okrem toho, vo vyššie uvedenom texte, wrappedClass nie je trieda, ale funkcia je manipulovaná s cieľom vrátiť typ triedy. Rád by som napísal ten istý spisovateľ:

def __call__(self, cls):
class wrappedClass(cls):
def __init__(self):
... some code here ...
return wrappedClass

Ako sa to dá urobiť?

Nie som si úplne istý, čo sa deje "" "... nejaký kód tu ..." ""

odpovede:

14 pre odpoveď č. 1

Ak chcete prepísať new_method(), Len to urob:

class Decorator(object):
def __init__(self, arg):
self.arg = arg
def __call__(self, cls):
class Wrapped(cls):
classattr = self.arg
def new_method(self, value):
return value * 2
return Wrapped

@Decorator("decorated class")
class TestClass(object):
def new_method(self, value):
return value * 3

Ak nechcete zmeniť __init__(), nemusíte ho prepísať.


2 pre odpoveď č. 2

Potom sa trieda NormalClass stáva ClassWrapper inštancie:

def decorator(decor_arg):

class ClassWrapper:
def __init__(self, cls):
self.other_class = cls

def __call__(self,*cls_ars):
other = self.other_class(*cls_ars)
other.field += decor_arg

return ClassWrapper

@decorator(" is now decorated.")
class NormalClass:
def __init__(self, name):
self.field = name

def __repr__(self):
return str(self.field)

test:

if __name__ == "__main__":

A = NormalClass("A");
B = NormalClass("B");

print A
print B
print NormalClass.__class__

Výkon:

A je teraz vyzdobená.
B je teraz vyzdobená.
__main __. classWrapper