实例方法classmethod和staticmethod之间的区别
首先要注意:静态方法和类方法也是函数,所以标准的函数规则大多适用于它们。我了解您的问题是关于 static 方法(没有传递额外的参数)和 class 方法(在第一个参数中接收类)之间的区别:
class Test(object):
def standard_method(*args, **kwargs):
# it is instance method (first argument will be instance)
return args, kwargs
@classmethod
def class_method(*args, **kwargs):
# it is class method (first argument will be class)
return args, kwargs
@staticmethod
def static_method(*args, **kwargs):
# it is static method (receives only arguments passed explicitly)
return args, kwargs
证明(或者更确切地说是不言自明的例子)在这里:
>>> t = Test()
>>> t.standard_method()
((<__main__.Test object at 0x0000000002B47CC0>,), {})
>>> t.class_method()
((<class '__main__.Test'>,), {})
>>> t.static_method()
((), {})
如您所见,传递的参数列表因您选择的方法类型而异。您面临的问题是参数数量可变。
解决方案
有一个解决方案 - 使用参数解包:
def some_decorator(func):
def wrapper(*args, **kwargs):
# do something here
# args is a tuple with positional args, kwargs is dict with keyword args
return func(*args, **kwargs)
return wrapper
之后,some_decorator 返回的函数将接受与修饰函数相同数量的参数。
所以这两个例子都可以工作:
@some_decorator
def say_hello():
print 'hello'
@some_decorator
def say_something(something):
print something
附录
为了给你一个完整的例子,如果你能使用这样的结构会很好(注意functools.wraps的用法):
from functools import wraps
def some_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
# do something here
# args is a tuple with positional args, kwargs is dict with keyword args
return func(*args, **kwargs)
return wrapper
原因在documentation for functools.wraps() 中列出:它保留了函数名和文档字符串,从而有效地使包装器看起来像一个被包装的函数(这有时很有用)。