自动装饰类中的每个实例方法 [英] Automatically decorating every instance method in a class

查看:119
本文介绍了自动装饰类中的每个实例方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想对给定类中的每个方法应用相同的装饰器,除了以 __ 开头和结尾的方法。

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:


  1. 为某些方法禁用此机制

  2. 为子类启用此机制

  3. 即使对于在运行时添加到此类的方法也启用此机制。

[注意:我使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆