我刚学Python那会,最头疼的就是类属性和实例属性。看了很多教程,还是迷迷糊糊的。你肯定也有过这种体验,写代码的时候脑子一团浆糊,不知道哪个属性该放哪。
别急。我今天用最直白的话跟你说清楚这件事。
先想一个场景。你是一个班主任,带一个班。班上有50个学生。班级的教室是固定的,所有学生都在这个教室里上课。每个学生的书包是自己的,里面装的东西各不一样。
这个教室就是类属性。全班共享。谁都能用,谁都能改。书包就是实例属性。一人一个,互不干扰。
写代码的时候怎么区分?类属性直接写在类里面,实例属性写在__init__方法里。我见过好多人把属性全堆在类里面,结果一个对象改了,所有对象都跟着变。这就是没分清。
给你看个例子。
class Student: school = '第一中学' 类属性,所有人都一样
def __init__(self, name):
self.name = name 实例属性,各人不同
这个school就是教室,name就是书包。school变了,全班学生的school都变。name变了,只影响这个学生自己。
你可能会问,什么时候用类属性?所有对象共用的常量,比如学校名字、公司名称、默认配置。这些写成类属性,省内存,管理也方便。每个对象独有的数据,比如名字、分数、账号密码,这些必须是实例属性。
还有个坑,新手容易踩。用实例去改类属性,看起来改了,其实只是给这个实例新加了一个实例属性,把同名的类属性盖住了。原来的类属性还在。这不是你想要的。
再说说查询顺序。你写一个obj.attr,Python先找obj有没有这个实例属性,没有就去找类的属性。再没有就找父类。类属性和实例属性同名的时候,实例属性优先。这个顺序记住就行。
我刚开始学的时候,总是写很长的类,把所有属性都放在类里面。后来发现代码改着改着就乱了。一个对象改了,其他对象莫名其妙也跟着变。排查半天,发现是类属性被当成实例属性用了。
你记住一个原则。属于整体共用的,用类属性。属于个体独有的,用实例属性。就这么简单。
再举个例子加深印象。你写一个游戏的玩家类。游戏版本号是所有玩家共用的,这是类属性。每个玩家的血量、位置、装备,这些都是实例属性。版本号升级,全服玩家都升级。血量变化,只影响这一个玩家。
明白了这个,你写代码的时候心里就有谱了。看到类定义,先想这个属性是所有对象都一样的,还是每个对象不一样的。想清楚了再写。代码会少很多bug。
你回去看看自己的代码,肯定能找到把类属性当实例属性用的地方。改过来就好了。这不是什么大问题,刚开始都会犯错。