类方法装饰器的一些问题

时间:2013-03-05 18:37:15

标签: python python-2.7 decorator class-method

我有一段代码,我想在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 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

刚刚看到一个关于装饰器的interesting post,这是解释,但它没有提供解决方法。

  

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

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

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

更新

这是关于如何正确实现描述符的另一个great post

答案 2 :(得分:-2)

也许问题出现在@classmethod def wrapper...之前(因为mydeco是函数定义而不是类定义)

答案 3 :(得分:-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)

现在可以使用