python 中的静态方法可以追溯到 Python 2.2 中所谓的“新式类”的引入。在此之前,类的方法只是普通的函数,存储为类的属性:
class OldStyleClass:
def method(self):
print "'self' is just the first argument of this function"
instance = OldStyleClass()
OldStyleClass.method(instance) # Just an ordinary function call
print repr(OldStyleClass.method) # "unbound method..."
对实例的方法调用经过特殊处理,可以自动将实例绑定到函数的第一个参数:
instance.method() # 'instance' is automatically passed in as the first parameter
print repr(instance.method) # "bound method..."
在 Python 2.2 中,大部分类系统都被重新思考和重新设计为“新型类”——继承自object
. 新型类的特征之一是“描述符”,本质上是类中的一个对象,负责描述、获取和设置类的属性。描述符有一个__get__
方法,该方法被传递给类和实例,并且应该返回类或实例的请求属性。
描述符使得使用单个 API 实现类属性的复杂行为成为可能,例如属性、类方法和静态方法。例如,staticmethod
描述符可以这样实现:
class staticmethod(object):
"""Create a static method from a function."""
def __init__(self, func):
self.func = func
def __get__(self, instance, cls=None):
return self.func
将此与普通方法的假设纯 Python 描述符进行比较,该描述符默认用于类属性中的所有普通函数(这与从实例中查找方法不完全一样,但它确实处理了自动“自我”争论):
class method(object):
"""Create a method from a function--it will get the instance
passed in as its first argument."""
def __init__(self, func):
self.func = func
def __get__(self, instance, cls=None):
# Create a wrapper function that passes the instance as first argument
# to the original function
def boundmethod(*args, **kwargs):
return self.func(self, *args, **kwargs)
return boundmethod
因此,当您编写 时method = staticmethod(method)
,实际上是在创建一个新的描述符,其工作是原封不动地返回原始函数,并将此描述符存储在类的“方法”属性中。
如果仅仅为了恢复原始功能,这似乎需要做很多工作——你是对的,它是。但是由于正常的方法调用是默认情况,静态方法和类方法需要分别实现,而描述符提供了一种通过一个简单的 API 启用这些和其他复杂行为的方法。
正如其他人已经指出的那样,Python 2.4 中引入的装饰器语法提供了一种更方便的方式来声明静态方法,但这只是一种语法上的便利,并没有改变静态方法的工作方式。
有关新样式的更多详细信息,请参见http://www.python.org/doc/2.2.3/whatsnew/sect-rellinks.html和http://users.rcn.com/python/download/Descriptor.htm类和描述符。