先给大家拜年,新年第一篇继续我复习面向对象的知识,这次打算说说我疑惑挺久的self,cls,staticmethod,classmethod是干嘛的,有什么用。
python:小型代码分析呀。
这里会说到:类方法,静态方法,类属性,实例方法等相关。先看一个例子:
class Person:
belong_to = 'earthman'
def __init__(self,skin, name):
self.skin = skin
self.name = name
def get_skin(self):
return self.skin
@classmethod
def menthod_cls(cls):
print(f'{cls},hello,{Person.belong_to}')
@staticmethod
def menthod_state():
print(f'hello,{Person.belong_to}')
lm = Person('yellow', '李明')
print(lm.get_skin())
print(Person.menthod_cls())
print(lm.menthod_cls())
print(Person.menthod_state())
#输出
yellow
<< span="">class '__main__.Person'>,hello,earthman
<< span="">class '__main__.Person'>,hello,earthman
hello,earthman
可以看到使用了classmethod或者staticmethod装饰后的方法,调用有些不一样,可以直接用类名.方法名()调用。
一开始我并没有get到这种做法有什么特别妙的地方,看了众多大佬的解读,总结出:
•减少实例化对象的开销,如果方法没有用到实例化的任何属性和方法,推荐使用静态类方法@staticmethod
•属于类的方法放到类里面,利于组织代码,容易阅读。
cls和self有什么特点
类的方法,第一个参数必须是self或者是cls(必须用classmethod装饰),这是一种约定。
cls,表示的是类本身,self表示实例化具体对象的本身。好比说在解析器执行代码的时候,具体的Person类也是一个对象,cls是Person的引用。slef就是lm对象的引用。
第一个参数为什么必须是cls或者self?将在下面最后讲到。
staticmethod和classmethod的特点
上面说到使用了这两者装饰的方法都可以用类.方法()调用,这两个有什么特点?
•@staticmethod,不需要self或者cls参数,静态方法,主要处理与这个类的逻辑关联, 如验证数据。注意,无法在静态类方法中使用实例化属性或者方法,比如上面的静态类方法:
@staticmethod
def menthod_state():
print(f'hello,{Person.belong_to}')
print(Person.get_skin())
以上使用了实例化self对象的方法会报错。我的理解是,带有self的方法,是实例化对象的方法,所以无法通过类对象来使用。
•@classmethod,第一个参数必须是cls,类方法,可以来调用类的属性,类的方法,实例化对象等,避免硬编码。比如上面使用类.方法(),实例化.方法()效果是一样的。重构类的时候不必要修改构造函数,只需要额外添加你要处理的函数(使用场景)。我在看scrapy代码中发现不少这类型的方法,现在想来确实是用在重构中多些,之前还看不懂。
为什么必须在方法定义和调用中显式使用“self”?
据说曾经有建议取消self,后来被python发明的大佬回答为什么必须带self的原因。首先self代表了实例化对象。比如:
lm = Person('yellow', '李明')
lm.get_skin()#类成员方法
#也可以这样使用,一样能用
Person.get_skin(lm)
lm现在是一个具体叫李明的人,那么在调用Person成员方法的时候,会隐式传递lm对象给get_skin(),也就是self。那为什么非要把self写到方法中?在官方python文档有解释:
在python中没有局部变量声明,加self就可以表示本实例化的变量/方法。可以理解成类里面的全局变量,局部变量和实例变量存在于两个不同的命名空间中,您需要告诉 Python 使用哪个命名空间。
那么对于cls参数其实也类似,必须告诉调用的方法,具体的类名,通过cls传递类对象进行调用。在重构的时候,也用得着。
以上就是本次阅读了大量资料后整理出的资料,希望对你们有帮助。
转载请注明:XAMPP中文组官网 » python面向对象中的self,cls,staticmethod,classmethod