我想对给定类中的每个方法应用相同的装饰器,除了那些以__
开头和结尾的方法。
在我看来,使用类装饰器应该是可行的。有什么陷阱需要注意吗?
理想情况下,我还希望能够:
1.通过用特殊的装饰器标记某些方法来禁用该机制
1.也为子类启用此机制
1.即使对于在运行时添加到此类的方法,也启用此机制
[Note:我使用的是Python 3.2,所以如果这依赖于最近添加的特性,我很好。]
下面是我的尝试:
_methods_to_skip = {}
def apply(decorator):
def apply_decorator(cls):
for method_name, method in get_all_instance_methods(cls):
if (cls, method) in _methods_to_skip:
continue
if method_name[:2] == `__` and method_name[-2:] == `__`:
continue
cls.method_name = decorator(method)
return apply_decorator
def dont_decorate(method):
_methods_to_skip.add((get_class_from_method(method), method))
return method
以下是我遇到的问题:
- 如何实现
get_all_instance_methods
函数 - 不确定我的
cls.method_name = decorator(method)
行是否正确 - 如何对在运行时添加到类中的任何方法执行相同的操作
- 如何将其应用于子类
- 如何实现
get_class_from_method
3条答案
按热度按时间bq3bfh9z1#
我认为这最好用元类来完成,以便处理运行时和子类方法装饰。我没有看到用类装饰器自动处理子类的优雅方法。
下面是一个使用它的例子(Python 2,但在Python 3中做了一些小的修改):
9vw9lbht2#
你可以这样做(虽然不确定这是否是最优雅的方式):
至于
cls.method_name
,您将不得不使用getattr(cls, method_name)
。kmpatx3s3#
这是@agf的答案的更新版本,它使用python 3,添加了类型提示(传递mypy),添加了docstring,并做了一个非常小的重构,装饰器在方法执行之前和之后都做了一些事情。
和它的使用示例: