自动装饰类中的每个实例方法 [英] Automatically decorating every instance method in a class
问题描述
我想对给定类中的每个方法应用相同的装饰器,除了以 __
开头和结尾的方法。
I want to apply the same decorator to every method in a given class, other than those that start and end with __
.
在我看来,它应该是可以使用类装饰器。是否有任何陷阱需要注意?
It seems to me it should be doable using a class decorator. Are there any pitfalls to be aware of?
理想情况下,我也希望能够:
Ideally, I'd also like to be able to:
- 为某些方法禁用此机制
- 为子类启用此机制
- 即使对于在运行时添加到此类的方法也启用此机制。
[注意:我使用Python 3.2, ]
[Note: I'm using Python 3.2, so I'm fine if this relies on features added recently.]
这是我的尝试:
_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
- how to implement
get_all_instance_methods
function - not sure if my
cls.method_name = decorator(method)
line is correct - how to do the same to any methods added to a class in runtime
- how to apply this to subclasses
- how to implement
get_class_from_method
推荐答案
我认为这是更好的做一个元类,以便处理运行时和子类方法装饰。我没有看到一个优雅的方式处理子类自动与类装饰器。
I think this is better done with a metaclass, in order to handle both runtime and subclass method decoration. I don't see an elegant way to handle subclasses automatically with a class decorator.
from types import FunctionType
# check if an object should be decorated
def do_decorate(attr, value):
return ('__' not in attr and
isinstance(value, FunctionType) and
getattr(value, 'decorate', True))
# decorate all instance methods (unless excluded) with the same decorator
def decorate_all(decorator):
class DecorateAll(type):
def __new__(cls, name, bases, dct):
for attr, value in dct.iteritems():
if do_decorate(attr, value):
dct[attr] = decorator(value)
return super(DecorateAll, cls).__new__(cls, name, bases, dct)
def __setattr__(self, attr, value):
if do_decorate(attr, value):
value = decorator(value)
super(DecorateAll, self).__setattr__(attr, value)
return DecorateAll
# decorator to exclude methods
def dont_decorate(f):
f.decorate = False
return f
它的使用示例(Python 2,但对Python 3进行了简单的修改):
And an example of its use (Python 2, but trivially modified for Python 3):
def printer(f):
print f
return f
class Foo(object):
__metaclass__ = decorate_all(printer)
def bar(self):
pass
@dont_decorate
def baz(self):
pass
@classmethod
def test(self):
pass
# prints
# <function bar at 0x04EB59B0>
class AnotherName(Foo):
def blah(self):
pass
# prints
# <function blah at 0x04EB5930>
Foo.qux = lambda: 1
# prints
# <function <lambda> at 0x04EB57F0>
这篇关于自动装饰类中的每个实例方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!