【发布时间】:2012-03-14 02:07:18
【问题描述】:
我见过很多 Python 装饰器的例子:
- 函数样式装饰器(包装函数)
- 类风格装饰器(实现
__init__、__get__和__call__) - 不带参数的装饰器
- 接受参数的装饰器
- “方法友好”的装饰器(即可以装饰类中的方法)
- “功能友好”的装饰器(可以装饰普通功能
- 可以装饰方法和函数的装饰器
但我从未见过一个可以完成上述所有操作的示例,而且我无法从特定问题的各种答案(例如 this one、this one 或 this one (which has one of the best answers I've ever seen on SO))综合起来,如何结合以上所有内容。
我想要的是一个基于类的装饰器,它可以装饰方法或函数, 至少需要一个附加参数。即,以便以下工作:
class MyDecorator(object):
def __init__(self, fn, argument):
self.fn = fn
self.arg = argument
def __get__(self, ....):
# voodoo magic for handling distinction between method and function here
def __call__(self, *args, *kwargs):
print "In my decorator before call, with arg %s" % self.arg
self.fn(*args, **kwargs)
print "In my decorator after call, with arg %s" % self.arg
class Foo(object):
@MyDecorator("foo baby!")
def bar(self):
print "in bar!"
@MyDecorator("some other func!")
def some_other_function():
print "in some other function!"
some_other_function()
Foo().bar()
我希望看到:
In my decorator before call, with arg some other func!
in some other function!
In my decorator after call, with arg some other func!
In my decorator before call, with arg foo baby!
in bar!
In my decorator after call, with arg foo baby!
编辑:如果重要的话,我使用的是 Python 2.7。
【问题讨论】:
-
“带参数的装饰器”只是一个带参数并返回装饰器的函数。
-
又为什么需要分别处理方法和函数呢?只需传递所有参数即可。
-
@katrielalex,一个方法作为一个普通函数开始它的生命,并作为一个存储在类中。当您查找一个方法时,它变成了一个绑定方法,其中函数的第一个参数将是您查找该方法的实例。当您拥有自己的类的实例而不是函数的对象时,它们不会自动执行此操作。
-
@Katriel 可能有一些非常特殊的情况,您必须以不同的方式处理方法和“常规”函数的装饰。
标签: python function methods arguments decorator