我有一段代码,我想在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__'
我不确定这个错误是否与第一个问题有关,但对我来说这看起来不同。欢迎任何解决这些问题的具体建议。
以上示例并没有真正“做”某些事情,它只是展示我所遇问题的最小可能示例。
答案 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时,它可能会因异常而失败。这是因为由这些包装器创建的包装器没有复制某些属性。
我既不知道如何正确装饰静态/类方法,但是当我遇到类似的异常时,我会执行以下操作之一,只是为了让我的代码在没有任何见解的情况下工作:
这是关于如何正确实现描述符的另一个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)
现在可以使用