问题描述
python类中定义方法有4种方式,分别是:
def f():
pass
def f(self):
pass
@staticmethod
def f():
pass
@classmethod
def f(cls):
pss
上述4种方式定义的方法,均可以通过类名.方法名和实例名.方法名访问,只是使用实例名.方法名的时候编译器会自动加上一个表示实例本身的参数;同样,调用classmethod方法时,编译器自动加上了实例对应的类型或类型本身作为参数,比如以下两种方法是等价的(通过类和实例均可调用方法):
class C:
def f(self):
print(C.f)
c = C()
C.f(c)
c.f()
即使是用@staticmethod修饰的方法,也可以用实例.方法名的方式调用,我的问题是:python真的有静态方法吗,python需要静态方法这个概念吗?
我自己的总结
大家看我说的是否有道理:
python中一般定义的方法形如:def fname(self),可以这样调用:实例.fname()。编译器会默认加一个参数,就是实例本身。也可以这样调用:类名.fname(实例)
形如 def fname()的方法,只可以使用 类名.fname()的模式调用,不可以使用 实例名.fname()的方式调用,因为编译器会自动加个参数(实例本身),和fname的参数不一致,报错
为了解决2的问题,python官方引入了 @staticmethod修饰(其实就是个装饰器),这样就可以形如 实例.fanme() 调用了
@classmethod修饰符完全是为了让程序员少写字,编译器默认会将实例对应的类型或类型本身作为参数传递
综上所述:python作者为了方便调用,而设计了系统自动补齐第一个参数为实例本身的功能,后来导致了问题2,于是打了补丁而出现了修饰符@staticmethod ,作者因为想不起更好的名字所有就叫 staticmethod了。There are only two hard things in Computer Science: cache invalidation and naming things.
谢谢
第一次来segmentfault问问题,如有冒犯,请多包涵。
静态方法你可以理解为一个语法糖,在底层实现的时候,往往是数据和函数之间的绑定。
1) 从语法上讲,静态方法类似于全局函数,但是隐藏在类的定义里,语法上看起来比全局函数清晰的很多,习惯OO思维的人很容易接受静态方法这个概念,而且Java/C++/C#这些主流的OO 都有静态方法的,从存在上是有必要的。
2) 类似的,类方法的存在也是必要的
3) 从调用层面上,python对静态方法做了扩展,如C++/Java里是不能直接用对象调用绑定静态方法的,但Python是一个动态语言,类型是在运行时绑定的,而非编译时绑定的,所以它用运行时的方法绑定支持
其中foo是一个静态方法,这是无可厚非的。
这里Line 850介绍了staticmethod是如何实现的
https://hg.python.org/cpython/file/69b416cd1727/Objects/funcobject.c