Bjö*_*lex 25 python design-patterns
我想在Python中实现装饰器模式,我想知道是否有一种方法可以编写一个装饰器来实现它想要修改的函数,而无需为所有刚转发到装饰对象的函数编写样板.像这样:
class foo(object):
def f1(self):
print "original f1"
def f2(self):
print "original f2"
class foo_decorator(object):
def __init__(self, decoratee):
self._decoratee = decoratee
def f1(self):
print "decorated f1"
self._decoratee.f1()
def f2(self): # I would like to leave that part out
self._decoratee.f2()
Run Code Online (Sandbox Code Playgroud)
我foo_decorator.f2想要decoratee.f2自动转发电话.有没有办法编写一个泛型方法,将所有未实现的函数调用转发给decoratee?
Phi*_*ipp 32
你可以使用__getattr__:
class foo(object):
def f1(self):
print "original f1"
def f2(self):
print "original f2"
class foo_decorator(object):
def __init__(self, decoratee):
self._decoratee = decoratee
def f1(self):
print "decorated f1"
self._decoratee.f1()
def __getattr__(self, name):
return getattr(self._decoratee, name)
u = foo()
v = foo_decorator(u)
v.f1()
v.f2()
Run Code Online (Sandbox Code Playgroud)
作为菲利普回答的附录; 如果您不仅要装饰,而且保留对象的类型,Python允许您在运行时子类化实例:
class foo(object):
def f1(self):
print "original f1"
def f2(self):
print "original f2"
class foo_decorator(object):
def __new__(cls, decoratee):
cls = type('decorated',
(foo_decorator, decoratee.__class__),
decoratee.__dict__)
return object.__new__(cls)
def f1(self):
print "decorated f1"
super(foo_decorator, self).f1()
u = foo()
v = foo_decorator(u)
v.f1()
v.f2()
print 'isinstance(v, foo) ==', isinstance(v, foo)
Run Code Online (Sandbox Code Playgroud)
这比您的示例所涉及的要多得多,您可以提前知道正在装饰的类.
这可能就足够了:
class foo_decorator(foo):
def __init__(self, decoratee):
self.__dict__.update(decoratee.__dict__)
def f1(self):
print "decorated f1"
super(foo_decorator, self).f1()
Run Code Online (Sandbox Code Playgroud)