实例方法classmethod
和staticmethod
首先要注意:静态方法和类方法也是函数,因此标准函数规则大多适用于它们。我了解您的问题是关于静态方法(没有传递额外的参数)和类方法(在第一个参数中接收类)之间的区别:
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
其原因在文档functools.wraps()
中列出:它保留了函数名称和文档字符串,有效地导致包装器看起来像一个包装的函数(有时很有用)。