繁体   English   中英

将装饰器应用于属性getter

[英]Applying a decorator to a property getter

根据上一个关于默认情况下记忆所有类方法的问题的回答,我正在使用这个元类:

from inspect import isfunction

class Immutable(type):
    def __new__(cls, name, bases, dct):
        for key, val in dct.items():
            # Look only at methods/functions; ignore those with
            # "special" names (starting with an underscore)
            if isfunction(val) and val.__name__[0] != '_':
                dct[key] = memoized(val)
            elif hasattr(val, 'fget'):
                # It's a property; we currently can't memoize these
                pass
        return type.__new__(cls, name, bases, dct)

这个元类具有将memoized的装饰器memoized中的所有函数和方法的效果。 唯一的问题是它不适用于属性。 (使用这个元类的类被视为不可变类,所以我只担心这里的readonly属性。)如果我尝试做类似的事情

from time import sleep

class Foo(object):
    __metaclass__ = Immutable

    @property
    def slow_calculation(self):
        sleep(5)    # simulate an intensive calculation
        return 4

然后slow_calculation没有被记忆 - 每次调用时都会有5秒的延迟,而不仅仅是第一次。

问题是property()返回一个property对象,而不是一个函数,因此元类的__new__isfunction测试不会捕获属性。 正如您所看到的,我添加了一个查找属性的测试,但后来我无法弄清楚如何将memoized decorator应用于属性getter fget 我想也许我可以说

elif hasattr(val, 'fget'):
    val.fget = memoized(val.fget)
    dct[key] = val

但是在这种情况下我得到了

Traceback (most recent call last):
  [...]
  File "utils.py", line 54, in __new__
    val.fget = memoized(val.fget)
TypeError: Error when calling the metaclass bases
    readonly attribute

是否有其他方法将装饰器应用于属性getter?

prop = property(memoized(prop.fget), prop.fset, prop.fdel, prop.__doc__)

不要修改属性; 做一个新的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM