5

我有一些代码,我想在 a 上使用装饰器,classmethod如下所示:

import functools

def mydeco(function):
    @classmethod
    def wrapper(cls):
        return function(cls) 
    return functools.update_wrapper(wrapper, function)
    # return wrapper

class BaseClass(object):
    @classmethod
    @mydeco
    def foo(cls):
        return "42" 

print BaseClass.foo()

当我注释掉@mydeco代码行时,即42打印文本。当包括这个装饰器时,我有几个问题:

  • 当使用更简单的线时,return wrapper我得到了错误

    TypeError: 'classmethod' object is not callable
    

如何正确地做到这一点,即在给定的示例中,返回原始函数而不进行更改。

  • 当使用更复杂的调用return functools.update_wrapper(wrapper, function)来保留一些原始功能时,我得到了错误

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

我不确定这个错误是否与第一个问题有关,但对我来说它看起来是一个不同的问题。欢迎任何解决这些问题的具体建议。

上面的示例并没有真正“做”某事,它只是显示我遇到的问题的最小可能示例。

4

4 回答 4

2

这对你不起作用有什么原因吗?

import functools

def mydeco(function):
    def wrapper(*args, **kwargs):
        return function(*args, **kwargs) 
    return functools.update_wrapper(wrapper, function)

class BaseClass(object):
    @classmethod
    @mydeco
    def foo(cls):
        return "42" 

print BaseClass.foo()
42
于 2013-03-05T20:41:05.603 回答
1

刚刚看到一篇关于装饰器的有趣帖子,这是解释,但它没有提供解决方法。

当在@classmethod 或@staticmethod 周围应用装饰器时,它可能会因异常而失败。这是因为由这些创建的包装器没有被复制的某些属性。

我都不知道如何正确装饰静态/类方法,但是当我遇到类似的异常时,我将执行以下操作之一,只是为了让我的代码在没有任何洞察力的情况下正常工作:

  • 更改@mydeco 和@staticmethod 的顺序
  • 丢弃@staticmethod

更新

这是关于如何正确实现描述符的另一篇精彩文章

于 2014-09-04T17:40:07.620 回答
-2

也许问题出在@classmethod前面def wrapper...(就像mydeco函数定义而不是类定义一样)

于 2013-03-05T18:43:43.293 回答
-3
from functools import wraps

def mydeco(function):
    @wraps(function)
    def wrapper(*args, **kwargs):
        print "Calling Decorated Function"
        return function(*args, **kwargs) 
    #return functools.update_wrapper(wrapper(function), function)
    return wrapper


@mydeco
class BaseClass():
    def foo(self, cls):
        return "42" 

a = BaseClass()
print a.foo(22)

现在可以了

于 2013-03-05T18:59:38.033 回答