带有@语法的python装饰器参数

标签 python decorator python-decorators

我正在尝试使用可以接受参数的缓存属性装饰器。

我查看了这个实现:http://www.daniweb.com/software-development/python/code/217241/a-cached-property-decorator

from functools import update_wrapper 

def cachedProperty (func ,name =None ):
  if name is None :
    name =func .__name__ 
  def _get (self ):
    try :
      return self .__dict__ [name ]
    except KeyError :
      value =func (self )
      self .__dict__ [name ]=value 
      return value 
  update_wrapper (_get ,func )
  def _del (self ):
    self .__dict__ .pop (name ,None )
  return property (_get ,None ,_del )

但我遇到的问题是,如果我想使用参数,我不能用@语法调用装饰器:

@cachedProperty(name='test') # This does NOT work
def my_func(self):
    return 'ok'

# Only this way works
cachedProperty(my_func, name='test')

如何使用带有装饰器参数的@语法?

谢谢

最佳答案

您需要一个装饰器工厂,这是另一个生产装饰器的包装器:

from functools import wraps 

def cachedProperty(name=None):
    def decorator(func):
        if decorator.name is None:
            decorator.name = func.__name__ 
        @wraps(func)
        def _get(self):
            try:
                return self.__dict__[decorator.name]
            except KeyError:
                value = func(self)
            self.__dict__[decorator.name] = value 
            return value 
        def _del(self):
            self.__dict__.pop(decorator.name, None)
        return property(_get, None, _del)
    decorator.name = name
    return decorator

将其用作:

@cachedProperty(name='test')
def my_func(self):
    return 'ok'

装饰器实际上只是语法糖:

def my_func(self):
    return 'ok'
my_func = cachedProperty(name='test')(my_func)

所以只要 @ 之后的表达式返回你的装饰器 [*] 表达式本身实际上做了什么并不重要。

在上面的例子中,@cachedProperty(name='test')部分首先执行了cachedProperty(name='test'),然后返回值call 用作装饰器。在上面的例子中,返回了decorator,所以my_func函数是通过调用decorator(my_func)来装饰的,调用的返回值是 property 对象,所以它将替换 my_func


[*] @ 表达式语法被有意限制在允许的范围内。您可以执行属性查找和调用,仅此而已,decorator grammar rule只允许在带点的名称末尾使用参数进行可选调用(其中点是可选的):

decorator               ::=  "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE)

这是一个 deliberate limitation的语法。

关于带有@语法的python装饰器参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22271923/

相关文章:

python - wx.Gauge在Windows中无法更新超过25%,在Linux中有效

python - 'or' 元组的大多数 pythonic 方式?

类的Python装饰器

Python 带参数的装饰器函数

python - 无法理解如何在装饰器内的包装函数内获取参数

python - 使用 Python API 运行 Ansible playbook

python - 设置正确的 python 设置脚本

python - 当参数是递归函数时装饰器如何工作?

python - 另一个函数定义中的函数定义 - 慢?

python - 是否可以使用装饰器在 Python 中进行 "extended"时间监控?