我想创建两个对象,以便为其他对象重复某些对象的方法。然后我尝试这样做:
def backup(method):
def wrapper(self, *args, **kwargs):
method(self, *args, **kwargs)
getattr(self.another_tester, method.__name__)(*args, **kwargs)
return wrapper
class Tester():
def __init__(self, name):
self.name = name
def select_backup(self, tester):
self.another_tester = tester
@backup
def foo1(self, stop=False):
print("I am tester {}, do method foo1".format(self.name))
@backup
def foo2(self, stop=False):
print("I am tester {}, do method foo2".format(self.name))
@backup
def foo3(self, stop=False):
print("I am tester {}, do method foo3".format(self.name))
tester1 = Tester("A")
tester2 = Tester("B")
tester1.select_backup(tester2)
tester2.select_backup(tester1)
tester1.foo1()
tester2.foo2()
tester1.foo3()
我得到RuntimeError: maximum recursion depth exceeded while calling a Python object
这样的代码。 class Tester
有很多不同的方法(foo1,foo2,foo3,...),我想backup
(重复)每个方法。所以我使用装饰。
我可以更改装饰器:
def backup(method):
def wrapper(self, *args, **kwargs):
method(self, *args, **kwargs)
try:
kwargs["stop"]
except KeyError:
getattr(self.another_tester, method.__name__)(stop=True, *args, **kwargs)
return wrapper
它的工作,但我认为还有更多的pythonic方式。任何人都可以提供这样的方式吗?
答案 0 :(得分:0)
如果你的对象总是同一个类的实例(或者至少,从来没有对装饰方法的不同实现),你可以更改装饰器,使它直接调用另一个实例上的原始方法,而不是通过getattr
获取装饰版本:
def backup(method):
def wrapper(self, *args, **kwargs):
method(self, *args, **kwargs)
method(self.another_tester, *args, **kwargs)
return wrapper
如果您希望能够支持不同类的对象(以及不同的方法实现),那么事情需要更复杂一些。您可以将对原始未修饰方法的引用保存为包装函数的属性,然后在需要时查找:
def backup(method):
def wrapper(self, *args, **kwargs):
method(self, *args, **kwargs)
other_method = getattr(self.another_tester, method.__name__).orig_method
other_method(self.another_tester, *args, **kwargs)
wrapper.orig_method = method
return wrapper