【发布时间】:2020-08-12 15:10:38
【问题描述】:
问题描述 我想使用装饰器来定义一个类方法,但这需要我在不需要提供时手动提供“自我”对象。
def func_wrapper(func):
def call_func(self):
print(self.a)
func()
return call_func
def func():
print('hello')
class test:
def __init__(self, func):
self.a = 0
self.call_func = func_wrapper(func)
mytest = test(func)
#mytest.call_func() #why does this not work?
mytest.call_func(mytest) #this works
我希望能够 mytest.call_func() 但这不起作用,大概是因为 call_func 绑定到 func_wrapper 而不是 mytest。如果我手动传入对象,例如mytest.call_func(mytest) 这将起作用,但我不想手动传入对象 - 如果继承测试类并编写自己的 call_func 方法,这会创建不一致的调用签名,因为这样该方法将是正确的绑定到班级。
解决方案尝试
def func_wrapper2(func, obj):
def call_func():
print(obj.a)
func()
return call_func
class test:
def __init__(self, func):
self.a = 0
self.call_func = func_wrapper2(func, self)
这是一个解决方案,可以让我根据需要 test.call_func(),但这里 func_wrapper 不是真正的装饰器,因为它也需要在对象中传递。
在网上我发现这个博客https://medium.com/@vadimpushtaev/decorator-inside-python-class-1e74d23107f6 讨论了这个问题,并建议在嵌套类或辅助类中定义装饰器。但是,他们的解决方案似乎不起作用,并且我因传递错误数量的输入而出现类型错误。
class test2:
class test2helper:
@classmethod
def func_wrapper(func):
print(self.a)
func()
def __init__(self):
self.a = 0
@test2helper.func_wrapper
def call_func(self):
print('hello')
那么在类方法中使用装饰器的正确方法是什么?每种方法似乎都会导致如何处理自我的不同问题。除非有更好的方法,否则我将使用 func_wrapper2 设计。
【问题讨论】:
-
在您的第一个 sn-p 中,
self.call_func = func_wrapper(func).__get__(self, test)。 -
不要将方法分配给实例,在类级别进行。
标签: python