Python 装饰方法导致方法传入对象
问题描述 我想使用装饰器来定义类方法,但这需要我在不需要提供“self”对象时手动提供该对象Python 装饰方法导致方法传入对象,python,Python,问题描述 我想使用装饰器来定义类方法,但这需要我在不需要提供“self”对象时手动提供该对象 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
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_包装,而不是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)
这是一个让我可以测试的解决方案。根据需要调用_func(),但这里的func_包装器不是真正的装饰器,因为它也需要在对象中传递
在网上我发现了这个博客,它讨论了这个问题,并建议在嵌套类或帮助类中定义decorator。然而,他们的解决方案似乎不起作用,我通过传递错误数量的输入而得到类型错误
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')
那么,在类方法中使用decorator的正确方法是什么呢?这样做的每一种方式似乎都会导致不同的自我处理问题。除非有更好的方法,否则我将使用func_包装器2设计 您缺少一个级别:
class test2:
class test2helper:
@classmethod
def decorator(cls, func): # this must return a function!
def func_wrapper(self): # ... namely this one, the "wrapper"
print(self.a) # ... where you have access to the instance
func(self) # ... upon which the method is called
return func_wrapper
def __init__(self):
self.a = 0
@test2helper.decorator
def call_func(self):
print('hello')
>>> t = test2()
>>> t.call_func()
0
hello
或者,如果要在不使用嵌套类的情况下继续先前的尝试:
def decorator(func): # you are decorating an unbound function!
def func_wrapper(obj):
print(obj.a)
func(obj) # which has to be passed all the arguments
return func_wrapper
class test:
def __init__(self):
self.a = 0
@decorator
def call_func(self):
print('hello')
您缺少一个级别:
class test2:
class test2helper:
@classmethod
def decorator(cls, func): # this must return a function!
def func_wrapper(self): # ... namely this one, the "wrapper"
print(self.a) # ... where you have access to the instance
func(self) # ... upon which the method is called
return func_wrapper
def __init__(self):
self.a = 0
@test2helper.decorator
def call_func(self):
print('hello')
>>> t = test2()
>>> t.call_func()
0
hello
或者,如果要在不使用嵌套类的情况下继续先前的尝试:
def decorator(func): # you are decorating an unbound function!
def func_wrapper(obj):
print(obj.a)
func(obj) # which has to be passed all the arguments
return func_wrapper
class test:
def __init__(self):
self.a = 0
@decorator
def call_func(self):
print('hello')
您可以定义一个类装饰器来执行您想要的操作:
def class_decorator(cls):
def call_func(self):
print(self.a)
return func()
setattr(cls, 'call_func', call_func)
return cls
def func():
print('hello')
@class_decorator
class Test:
def __init__(self, func):
self.a = 0
mytest = Test(func)
mytest.call_func() # This now works.
输出:
0
你好
您可以定义一个类装饰器来执行您想要的操作:
def class_decorator(cls):
def call_func(self):
print(self.a)
return func()
setattr(cls, 'call_func', call_func)
return cls
def func():
print('hello')
@class_decorator
class Test:
def __init__(self, func):
self.a = 0
mytest = Test(func)
mytest.call_func() # This now works.
输出:
0
你好
在您的第一个代码段中,self.call\u func=func\u wrapper(func)。\uu获取(self,test)
不要将方法分配给实例,在类级别执行。在您的第一个代码段中,self.call\u func=func\u wrapper(func)。\uu获取(self,test)
不要将方法分配给实例,在类级别执行。