在本文中,我将试图解释什么是staticmethod和classmethod,和什么区别它们之间。staticmethod并且classmethod都使用装饰器将方法定义为staticmethod或classmethod
在class中大多数的方法是实例方法,即将实例作为第一个参数传递给方法。
下面是一个基础类的实例:
class Kls(object):
def __init__(self, data):
self.data = data
def printd(self):
print(self.data)
ik1 = Kls('arun')
ik2 = Kls('seema')
ik1.printd()
ik2.printd()
输出结果:
arun
seema
Python解释器自己会做这些操作的.如果现在我们想写一些仅仅与类交互而不是和实例交互的方法会怎么样呢? 我们可以在类外面写一个简单的方法来做这些,但是这样做就扩散了类代码的关系到类定义的外面. 如果像下面这样写就会导致以后代码维护的困难:
def get_no_of_instances(cls_obj):
return cls_obj.no_inst
class Kls(object):
no_inst = 0
def __init__(self):
Kls.no_inst = Kls.no_inst + 1
ik1 = Kls()
ik2 = Kls()
print(get_no_of_instances(Kls))
输出:
2
简言之,该装饰器修饰的方法是对类中的元素进行操作。而不是对实例进行操作的。
如果我们想获得实例的数量,我们所要做的就是如下所示:
def iget_no_of_instance(ins_obj):
return ins_obj.__class__.no_inst
class Kls(object):
no_inst = 0
def __init__(self):
Kls.no_inst = Kls.no_inst + 1
ik1 = Kls()
ik2 = Kls()
print iget_no_of_instance(ik1)
使用@classmethod之后的代码
class Kls(object):
no_inst = 0
def __init__(self):
Kls.no_inst = Kls.no_inst + 1
@classmethod
def get_no_of_instance(cls_obj):
return cls_obj.no_inst
ik1 = Kls()
ik2 = Kls()
print ik1.get_no_of_instance()
print Kls.get_no_of_instance()
好处:
无论我们从实例还是类中调用方法,它将该类作为第一个参数传递
通常有一些与类相关的功能,但不需要类或任何实例来做一些工作。也许像设置环境变量,改变另一个类中的属性等等。在这种情况下,我们也可以使用一个函数,但是这样做也会扩展相关的代码,以后可能导致维护问题
IND = 'ON'
def checkind():
return (IND == 'ON')
class Kls(object):
def __init__(self,data):
self.data = data
def do_reset(self):
if checkind():
print('Reset done for:', self.data)
def set_db(self):
if checkind():
self.db = 'new db connection'
print('DB connection made for:',self.data)
ik1 = Kls(12)
ik1.do_reset()
ik1.set_db()
使用@staticmethod的代码
IND = 'ON'
class Kls(object):
def __init__(self, data):
self.data = data
@staticmethod
def checkind():
return (IND == 'ON')
def do_reset(self):
if self.checkind():
print('Reset done for:', self.data)
def set_db(self):
if self.checkind():
self.db = 'New db connection'
print('DB connection made for: ', self.data)
ik1 = Kls(12)
ik1.do_reset()
ik1.set_db()
class Kls(object):
def __init__(self, data):
self.data = data
def printd(self):
print(self.data)
@staticmethod
def smethod(*arg):
print('Static:', arg)
@classmethod
def cmethod(*arg):
print('Class:', arg)
>>> ik = Kls(23)
>>> ik.printd() # 实例调用其属性或者方法
23
>>> ik.smethod()
Static: ()
>>> ik.cmethod()
Class: (<class '__main__.Kls'>,)
>>> Kls.printd() #printd()是实例方法,故使用类直接调用会报错
TypeError: unbound method printd() must be called with Kls instance as first argument (got nothing instead)
>>> Kls.smethod() # 静态类方法,没有传递任何参数
Static: ()
>>> Kls.cmethod() # 类方法,第一个参数是该类
Class: (<class '__main__.Kls'>,)
总结:
@staticmethod
@classmethod
http://pythoncentral.io/difference-between-staticmethod-and-classmethod-in-python/