[英]Python: decorate __call__ and ordinary function with the same decorator?
在Python 2.6-2.7中是否可以使用相同的装饰器执行以下任务:
class ComplextCallableObject(object):
@wrap_me
def __call__(self, a1, a2):
pass
@wrap_me
def simple_function(a1, a2):
pass
ComplextCallableObject.__call__
和simple_function
都具有相同的args,但__call__
也具有第一个arg的self
。 在wrap_me
装饰器中,我需要访问被包装的函数args。
不幸的是,在定义时(本例中为类块),除了命名约定之外,代码无法告诉函数如何使用。 稍微修改你的例子:
class ComplextCallableObject(object):
@wrap_me
def __call__(self, a1, a2):
pass #...
@wrap_me
def simple_function(tgt, a1, a2):
pass
ComplextCallableObject.anInstanceMethod = simple_function
ComplextCallableObject.anClassMethod = classmethod(simple_function)
ComplextCallableObject.aStaticMethod = staticmethod(simple_function)
在这种情况下, simple_function
正在实现一个采用目标和两个参数的函数,一个采用两个参数的实例方法,一个采用两个参数的类方法,一个采用目标和两个参数的静态方法。 但是这些用法在定义函数之后才会被绑定。 staticmethod
和classmethod
返回不同的对象类型,因此如果需要,您可以区分它们。
如果您确实想使用约定,则可以检查函数的第一个参数名称以查看它是否为self
:
def wrap_me(fn):
names = fn.func_code.co_varnames
if names and names[0]=='self':
print 'looks like an instance method'
else: print 'looks like a function'
return fn
def wrap_me(*args):
a1, a2 = args if len(args) == 2 else args[1:]
...
当然,如果在类方法上调用了wrap_me
,则需要修改返回的函数以获取self
参数。
顺便说一句,假设你实际上没有在你正在装饰的函数中使用self
,它应该是一个静态的方法。
这可能相当愚蠢,但也可能适用于最简单的情况:
In [1]: def wrap_me(func):
...: def wrapped(*args):
...: print 'arg1 is', args[-2]
...: print 'arg2 is', args[-1]
...: func(*args)
...: return wrapped
...:
In [2]: class ComplexCallableObject(object):
...: @wrap_me
...: def __call__(self, a1, a2):
...: print 'class object called'
...:
In [3]: @wrap_me
...: def simple_function(a1, a2):
...: print 'function called'
...:
In [4]: simple_function('A', 'B')
arg1 is A
arg2 is B
function called
In [5]: o = ComplexCallableObject()
In [6]: o('A', 'B')
arg1 is A
arg2 is B
class object called
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.