functools.wrapper - AttributeError: 'type' 对象的属性 '__doc__' 不可写

use*_*738 5 decorator python-2.7 functools dictionary-missing

在执行下面的代码时,我得到AttributeError: attribute '__doc__' of 'type' objects is not writable.

from functools import wraps

def memoize(f):
    """ Memoization decorator for functions taking one or more arguments.
        Saves repeated api calls for a given value, by caching it.
    """
    @wraps(f)
    class memodict(dict):
       """memodict"""
       def __init__(self, f):
           self.f = f
       def __call__(self, *args):
           return self[args]
       def __missing__(self, key):
           ret = self[key] = self.f(*key)
           return ret
     return memodict(f)

@memoize
def a():
    """blah"""
    pass
Run Code Online (Sandbox Code Playgroud)

追溯:

from functools import wraps

def memoize(f):
    """ Memoization decorator for functions taking one or more arguments.
        Saves repeated api calls for a given value, by caching it.
    """
    @wraps(f)
    class memodict(dict):
       """memodict"""
       def __init__(self, f):
           self.f = f
       def __call__(self, *args):
           return self[args]
       def __missing__(self, key):
           ret = self[key] = self.f(*key)
           return ret
     return memodict(f)

@memoize
def a():
    """blah"""
    pass
Run Code Online (Sandbox Code Playgroud)

即使提供了文档字符串,我也不知道这有什么问题。

如果没有包装它工作正常,但我需要这样做。

nco*_*lan 1

@wraps(f)主要设计用作函数装饰器,而不是类装饰器,因此将其用作后者可能会导致偶尔出现奇怪的问题。

您收到的具体错误消息与 Python 2 上内置类型的限制有关:

>>> class C(object): pass
... 
>>> C.__doc__ = "Not allowed"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: attribute '__doc__' of 'type' objects is not writable
Run Code Online (Sandbox Code Playgroud)

如果您使用Python 3,切换到Python 2中的经典类(通过继承而UserDict.UserDict不是dict内置),或者使用闭包来管理结果缓存而不是类实例,装饰器将能够从底层函数。