python的classmethod和staticmethod小谈
2016-04-13
概念
python 的classmethod 与staticmethod 这两个有什么区别? 二者又有什么联系? 在google和baidu之后, 得到的大致的联系就是二者都是对类的方法的静态调用的装饰器, 即对类的方法的静态调用可以用这两种方式实现。 区别体现在classmethod 也可以用类的实例调用, 而staticmethod 则不能如此
原因
假设 class A 中 使用 classmethod 装饰函数 a, 如下:
class A():
_info = "hello world"
@classmethod
def a(arg):
print arg._info
那么对a的调用既可以直接类似静态调用
A.a()
也可以先实例化, 再调用:
aaa = A()
aaa.a()
但如果把classmethod 换成staticmehtod:
class A():
_info = "hello world"
@staticmethod
def a(arg):
print arg._info
就只能静态调用了(staticmethod 名字就已经看得出来了)
原因是, classmethod 是类(不是实例化的对象)作为第一个参数传递给了函数, 比如在第一个例子里的aaa.a()和A.a(), 都是直接将类
或者对象的类(再一次, 不是实例)
传递进去, 进而实现静态调用
而staticmethod 只是将函数声明为静态方法, 没有传递任何内容进去
静态变量范围
在实验过程中, 类的静态变量对类的实例产生了一些有趣的影响, 如下
class c():
_num = 0
def add(self,num):
self._num += nu
def add_c(self,num)
c._num += num
def get(self):
return self._nu
def get_c(self):
return c._num
if __name__ == "__main_
c1 = c()
c2 = c()
c1.add_c(3)
c2.add_c(2)
c1.add(9)
c2.add(4)
print c1.get()#?
print c2.get()#?
print c1.get_c()#?
print c2.get_c()#?
结果依次应该是什么呢,如下 14 9 5 5
让我们产生疑问的是第一个和第二个的结果怎么是14 和 9, 很明显3+2+9 = 14, 3+2+4 = 9, 是通过这两种方式的结果, 看起来就像 add_c 里的类的变量影响了 add里的类的实例。
确实如此, 对类的变量的修改会影响类的实例的变量的使用, 所以我们在通过 classname.variable 的方式对类变量做修改的时候一定要小心。
而类的实例并不会影响类的静态变量,只是会修改对象实例本身的值, 所以后面两个的结果总是5,5
同样, 如果我们使用classmethod 和staticmethod
@staticmethod
def get_sm():
return c._num
@classmethod
def get_cm(arg):
print arg
return arg._num
结果也将仅仅是静态变量变化后的结果, 与类的实例无关
PS: 以上是对classmethod 和staticmethod 的暂时做的了解的总结, 如有纰漏, 请及时指正