[英]Python: decorate __call__ and ordinary function with the same decorator?
Is it possible in Python 2.6-2.7 to use the same decorator for the following task: 在Python 2.6-2.7中是否可以使用相同的装饰器执行以下任务:
class ComplextCallableObject(object):
@wrap_me
def __call__(self, a1, a2):
pass
@wrap_me
def simple_function(a1, a2):
pass
Both ComplextCallableObject.__call__
and simple_function
has the same args, but __call__
also has self
for the first arg. ComplextCallableObject.__call__
和simple_function
都具有相同的args,但__call__
也具有第一个arg的self
。 In the wrap_me
decorator I need an access for the function being wrapped args. 在wrap_me
装饰器中,我需要访问被包装的函数args。
Unfortunately, at the time of definition (the class block in this case), the code cannot tell how a function will be used except by naming convention. 不幸的是,在定义时(本例中为类块),除了命名约定之外,代码无法告诉函数如何使用。 Modifying your example a bit: 稍微修改你的例子:
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)
In this case, simple_function
is implementing a function taking a target and two parameters, an instance method taking two parameters, a class method taking two parameters, and a static method taking a target and two parameters. 在这种情况下, simple_function
正在实现一个采用目标和两个参数的函数,一个采用两个参数的实例方法,一个采用两个参数的类方法,一个采用目标和两个参数的静态方法。 But these uses are not bound until after the function is defined. 但是这些用法在定义函数之后才会被绑定。 Both staticmethod
and classmethod
return a different object type, so you can tell those apart, if need be. staticmethod
和classmethod
返回不同的对象类型,因此如果需要,您可以区分它们。
If you did want to use convention, you could inspect the function's first argument name to see if it is self
: 如果您确实想使用约定,则可以检查函数的第一个参数名称以查看它是否为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:]
...
Of course, you will need to modify the returned function to take the self
argument if wrap_me
was called on a class method as well. 当然,如果在类方法上调用了wrap_me
,则需要修改返回的函数以获取self
参数。
By the way, assuming you're not actually using self
inside the function which you're decorating, it should really be a static method. 顺便说一句,假设你实际上没有在你正在装饰的函数中使用self
,它应该是一个静态的方法。
This may be pretty dumb, but might as well work for the simplest case: 这可能相当愚蠢,但也可能适用于最简单的情况:
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.