【问题标题】:Memoize decorator not returning actual valueMemoize 装饰器不返回实际值
【发布时间】:2015-08-23 17:03:38
【问题描述】:

我有这个memoize 装饰器:

import functools

cache = {}

def memoize(obj):
    @functools.wraps(obj)
    def memoizer(*args, **kwargs):
        if args not in cache:
            cache[args] = obj(*args, **kwargs)
        return cache[args]
    return memoizer

它适用于类的任何方法。但是,与 @property 装饰器一起使用时会出现以下错误。

AttributeError: 'property' object has no attribute '__module__'

如何使其与类的 @property 方法一起使用?

提前致谢!

更新

class QClass(object):
    @memoize
    @property
    def positive(self):
        return Predicate('positive')

【问题讨论】:

  • this post 有帮助吗?
  • 我不确定。让我从那里尝试一些事情。
  • 嗯,我猜这与 functools.wraps 如何在 module 上复制和其他事情有关。当你说你将它与@property 一起使用时,我能看到你正在做的事情的上下文吗?

标签: python


【解决方案1】:

由于property对象错过__module__等属性,你应该把它的装饰器应用到最后一个:

class QClass(object):
    @property
    @memoize
    def positive(self):
        return Predicate('positive')

或者在 memoize 装饰器中指定分配的可用属性:

def memoize(obj):
    @functools.wraps(obj, assigned=('__doc__',))
    def memoizer(*args, **kwargs):
        …

【讨论】:

    【解决方案2】:

    这是我的一个同事回答的。

    装饰器可以这样写:

    from functools import update_wrapper
    predicate_cache = {}
    
    def cached_property(cache):
        """Create a property, where the lookup is stored in ``cache``"""
        def decorator(method):
            name = method.__name__
            def wrapper(self):
                if name not in cache:
                    cache[name] = method(self)
                return cache[name]   
            return property(update_wrapper(wrapper, method))
        return decorator
    

    而且可以这样使用:

    predicate_cache = {}
    
    class QClass(object):
        @cached_property(predicate_cache)
        def positive(self):
            """..."""
            return Predicate("positive")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-27
      • 2020-12-04
      • 1970-01-01
      • 1970-01-01
      • 2015-11-21
      • 1970-01-01
      • 2020-02-10
      • 2014-05-19
      相关资源
      最近更新 更多