将 self 方法作为参数传递给装饰器
Passing a method of self to decorator as an argument
我有一个class A,里面有很多旧的复杂方法,我重写了。
class A:
def __init__(self):
self.x = 1
def old_func(self):
return 2
@property
def b(self):
if not hasattr(self, 'b'):
self._b = B(self)
return _b
class B:
def __init__(self, a: A):
self.a = a
def new_func(self):
return 2
我想逐渐用`a.new_func代替a.old_func
。但首先,我想确保新方法始终以与旧方法相同的方式工作。所以我写了一个装饰器来检查:
def refactor_factory(new_func):
def refactor(old_func):
def _wrapper(*args, **kwargs):
old_return_value = old_func(*args, **kwargs)
new_return_value = new_func(**kwargs)
if old_return_value != new_return_value:
raise Exception("Mismatch") # Add a complete log info
return old_return_value
return _wrapper
return refactor
我想这样称呼它:
class A:
def __init__(self):
self.x = 1
@refactor_factory(self.b.new_func)
def old_func(self):
return 2
def new_func(self):
return 2
问题是我无法将 new_func 传递给装饰器。我知道我可以在装饰器中访问 self
,但是在传递参数时,我无权访问它,因此我无法传递它的方法。有什么办法可以实现吗?
p.s。我知道有不同的设计可以实现我想要的,如下图所示,我只是觉得第一种方式更简洁。
def refactor(old_func):
def _wrapper(*args, **kwargs):
self = args[0]
if isinstance(old_func, self.old_func):
new_func = self.b.new_func
old_return_value = old_func(*args, **kwargs)
new_return_value = new_func(**kwargs)
if old_return_value != new_return_value:
raise Exception("Mismatch") # Add a complete log info
return old_return_value
return _wrapper
class A:
def __init__(self):
self.x = 1
@refactor_factory
def old_func(self):
return 2
def new_func(self):
return 2
我想你可以通过 A.new_func
。在包装器中,self
将是 *args
之一,因此它会被正确传递。
class A:
def __init__(self):
self.x = 1
@refactor_factory(A.new_func)
def old_func(self):
return 2
def new_func(self):
return 2
我有一个class A,里面有很多旧的复杂方法,我重写了。
class A:
def __init__(self):
self.x = 1
def old_func(self):
return 2
@property
def b(self):
if not hasattr(self, 'b'):
self._b = B(self)
return _b
class B:
def __init__(self, a: A):
self.a = a
def new_func(self):
return 2
我想逐渐用`a.new_func代替a.old_func
。但首先,我想确保新方法始终以与旧方法相同的方式工作。所以我写了一个装饰器来检查:
def refactor_factory(new_func):
def refactor(old_func):
def _wrapper(*args, **kwargs):
old_return_value = old_func(*args, **kwargs)
new_return_value = new_func(**kwargs)
if old_return_value != new_return_value:
raise Exception("Mismatch") # Add a complete log info
return old_return_value
return _wrapper
return refactor
我想这样称呼它:
class A:
def __init__(self):
self.x = 1
@refactor_factory(self.b.new_func)
def old_func(self):
return 2
def new_func(self):
return 2
问题是我无法将 new_func 传递给装饰器。我知道我可以在装饰器中访问 self
,但是在传递参数时,我无权访问它,因此我无法传递它的方法。有什么办法可以实现吗?
p.s。我知道有不同的设计可以实现我想要的,如下图所示,我只是觉得第一种方式更简洁。
def refactor(old_func):
def _wrapper(*args, **kwargs):
self = args[0]
if isinstance(old_func, self.old_func):
new_func = self.b.new_func
old_return_value = old_func(*args, **kwargs)
new_return_value = new_func(**kwargs)
if old_return_value != new_return_value:
raise Exception("Mismatch") # Add a complete log info
return old_return_value
return _wrapper
class A:
def __init__(self):
self.x = 1
@refactor_factory
def old_func(self):
return 2
def new_func(self):
return 2
我想你可以通过 A.new_func
。在包装器中,self
将是 *args
之一,因此它会被正确传递。
class A:
def __init__(self):
self.x = 1
@refactor_factory(A.new_func)
def old_func(self):
return 2
def new_func(self):
return 2