我目前有一个将函数包装到类中的装饰器。
(我们目前正在使用这个奇怪的自定义异步框架,其中每个异步调用被定义为具有大量样板代码的类。我的想法是只修饰函数然后返回适当的类。)
这个装饰器可以很好地处理类之外的函数。但是,在将它与方法一起使用时,self
参数不再隐式传递,我不确定原因。
这是我可以放在一起的最好的例子
from __future__ import print_function
import functools
def test_wrap(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print("Args:", args)
print("Kwargs:", kwargs)
func(*args, **kwargs)
return wrapper
def test_class_wrap(func):
"""Return a Command object for use with the custom framework we are using."""
@functools.wraps(func, assigned=('__name__', '__module__'), updated=())
class Command(object):
def __init__(self, *args, **kwargs):
print("Args:", args)
print("Kwargs:", kwargs)
func(*args, **kwargs)
return Command
class MyObject(object):
def __init__(self):
self.value = 100
@test_wrap
def foo(self):
print(self.value)
@test_class_wrap
def bar(self):
print(self.value)
if __name__ == '__main__':
obj = MyObject()
obj.foo()
print()
obj.bar(obj) # works
# obj.bar() # TypeError: bar() takes exactly 1 argument (0 given)
# Why is self implicitly passed as an argument like with outher methods?
# Output
# Args: (<__main__.MyObject object at 0x7fe2bf9bb590>,)
# Kwargs: {}
# 100
# Args: (<__main__.MyObject object at 0x7fe2bf9bb590>,)
# Kwargs: {}
# 100
答案 0 :(得分:1)
test_class_wrap
什么都不做,只是返回一个类,因此__init__
没有被调用。尝试使用传递args和kwargs的函数来包装类:
def test_class_wrap(func):
"""Return a Command object for use with the custom framework we are using."""
@functools.wraps(func, assigned=('__name__', '__module__'), updated=())
def wrapper(*args, **kwargs):
class Command(object):
def __init__(self, *args, **kwargs):
print("Args:", args)
print("Kwargs:", kwargs)
func(*args, **kwargs)
return Command(*args, **kwargs)
return wrapper
...
if __name__ == '__main__':
obj = MyObject()
obj.foo()
print()
obj.bar()