python - Python 中的可定制装饰器

标签 python decorator

我想提供一个装饰器,允许在应用于函数时进行可选配置。

一个简单的实现如下:

import functools


class Deco(object):
    config = {'message': 'hello'}

    def __init__(self, func):
         self.func = func
         functools.wraps(func)(self)

    def __call__(self, *args, **kwargs):
         print self.config['message']
         return self.func(*args, **kwargs)

    @classmethod
    def customize(cls, **kwargs):
         """Return a customized instance of this class. """
         return type(cls.__name__, (Deco, ), {'config': kwargs})


@Deco
def add(a, b): 
    return a + b 


@Deco.customize(message='bye')
def sub(a, b): 
    return a - b 


>>> add(1, 2)
'hello'
>>> sub(2, 1)
'bye'

我想用它为 Django View 提供用户友好的装饰器。

这种方法可以正常工作,不会出现错误,但是作为装饰器,允许类拥有静态工厂方法来实例化其自身的自定义实例有什么不好吗?

最佳答案

您可以在每次使用装饰器时无需创建额外的子类,但您的代码很好。没有额外子类的方式可能是这样的:

class Deco(object):
    config = {'message': 'hello'}

    def __init__(self, func=None, **kwargs):
         if kwargs:
             self.config = kwargs
         if func is not None:
             self._decorate(func)

    def _decorate(self, func):
        self.func = func
        functools.wraps(func)(self)

    def __call__(self, *args, **kwargs):
        if not hasattr(self, "func"):
            self._decorate(func)
            return self
        print self.config['message']
        return self.func(*args, **kwargs)

因此,虽然性能方面,您的代码不会有任何区别(除非您要装饰至少数十万个函数 - 您的代码每次使用装饰器时都会创建一个额外的对象 - 一个类,除了该类的实例) - 这会对人们审查您的代码(无论是使用您的模块,还是在完成后维护它)产生影响。我的意思是“动态生成自身子类的装饰器”可能听起来太先进并且会吓跑人们。尽管它就像我上面的建议一样简单,但一旦像您一样了解了 Python 中的类生成机制。

关于python - Python 中的可定制装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12939012/

相关文章:

python - 正确剥离 : char with Regex

python - 如何在 SQLAlchemy 中嵌套连词 or and 和 _

reactjs - React-MobX 错误 : The 'decorators' plugin requires a 'decoratorsBeforeExport' option, 其值必须是 bool 值

python-3.x - 运行 tmp() 的结果是什么以及为什么?

javascript - 类索引装饰器和列装饰器有什么区别?

python - 我正在尝试检测屏幕上的移动但收到错误 : ValueError: too many values to unpack (expected 4)

python - 检查 websocket 客户端的 URL - python

python - 如何使用 python 的 httplib2 保存文件?

python - python 中的互斥装饰器

python - 从语法上推迟函数执行