概述
之前介绍了实例属性(对象属性),其实类还有 类属性。与C++、java的类的静态变量类似,但写法不同
应用场景
一般情况下,在类的 所有对象都需要共同访问一个属性 时,就应该用类属性
比如我们创建 moto手机 类 MotoPhone,该类的 商标 属性 logo 就是 类属性
根据该类创建的所有对象,都有 商标 属性 logo,而且共用一个,被联想收购后,修改一次,就可以了
注意:
类属性属于类,在内存中只存在一份,该类的所有对象访问类属性时,都指向同一个内存
类属性 vs 实例属性
尽量把用户 传入的属性 定义为 实例属性,而把所有对象中都一样的属性作为 类属性。实例属性在每创造一个实例时都会初始化一遍,不同的实例的实例属性可能不同,不同实例的 类属性都相同,从而 减少内存。
定义
方式一:
定义在类里,方法外(推荐)
class MotoPhone:
logo="moto"
mp=MotoPhone()
print(MotoPhone.__dict__)#有logo属性
print(mp.__dict__)#没有logo属性,因为logo属性属于类
方式二:
动态 添加属性(不推荐)
class MotoPhone:
pass
mp=MotoPhone()
MotoPhone.logo="moto"#动态添加属性
print(MotoPhone.__dict__)#有logo属性
print(mp.__dict__)#没有logo属性,因为logo属性属于类
注意:不要通过对象定义类属性
使用 对象.属性=值 的写法,是 动态 给对象添加 实例属性(见 链接
)
class MotoPhone:
pass
mp=MotoPhone()
mp.logo="moto"#这种写法是动态添加对象属性,对象属性对象属性
print(MotoPhone.__dict__)#没有logo属性
print(mp.__dict__)#有logo属性
注意:
类属性和对象属性不要同名,会造成混乱
访问
方式一:
通过 类名.类属性名
class MotoPhone:
logo="moto"
mp=MotoPhone()
print(MotoPhone.logo)
方式二:
通过 对象名.类属性名
class MotoPhone:
logo="moto"
mp=MotoPhone()
print(mp.logo)
修改类属性
方式一:
通过类名修改(不推荐)
class MotoPhone:
logo="moto"
mp=MotoPhone()
MotoPhone.logo="lenove"
print(MotoPhone.__dict__)#有logo属性
print(mp.__dict__)#没有logo属性,因为logo属性属于类
注意
这种方式不合理,比如修改logo时,可能对 长度有限制、不能有数字等,所以不推荐这种方式
方式二:
通过类方法,后面会讲到
私有类属性
同对象的私有属性一样,类属性也有 私有 和 公有,上面定义的方式都是公有类属性。
方式一
私有类属性的前面有 两个下划线 _ _
注意:
- python解释器会对私有类属性做改名处理
- 私有类属性,不要在类外部使用,一般在 类方法中使用
class MotoPhone:
__logo="moto"
mp=MotoPhone()
print(MotoPhone.__dict__)#有logo属性
print(mp.__dict__)#没有logo属性,因为logo属性属于类
总结
根据结果可知:在python官方解释器中,将私有类属性改名为:_类名__属性名。(注意不同的解释器处理方式可能不同)
方式二
私有类属性的前面有 一个下划线 _ ,这是程序员之间的约定,当看到有下划线时,就不要直接改动
可继承
class MotoPhone:
_logo="moto"
class NewMotoPhone(MotoPhone):
pass
print(dir(MotoPhone))#有logo属性
print(dir(NewMotoPhone))#有logo属性
print(MotoPhone._logo)
print(NewMotoPhone._logo)
类属性 与 父子类
子类可以继承父类的非私有类属性
子类 继承 父类的 类属性
class Wangjianlin:
_last_name='王'
class Wangsicong(Wangjianlin):
pass
print(dir(Wangsicong))
执行结果可以看到 类 Wangsicong 有 _last_name 属性
可以通过 子类名 访问父类的类属性
print(Wangjianlin._last_name)
print(Wangsicong._last_name)
不能通过 子类名 修改父类的 类属性
Wangsicong._last_name="张"
print(Wangjianlin._last_name)
print(Wangsicong._last_name)
结果如下:
王
张
也就是 子类 动态添加 类属性
总结
- 类属性属于类,可以直接通过类访问和修改
类名.类属性 - 该类创建的对象也可以直接访问类属性,
对象.类属性 - 在内存中只存在一个(该类的对象访问的类属性,是同一个)
- 私有类属性(开头两个下划线),不可以继承(本质还是可以继承,且做了改名处理)



