python面向对象-类属性和访问权限

概述

之前介绍了实例属性(对象属性),其实类还有 类属性。与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时,可能对 长度有限制、不能有数字等,所以不推荐这种方式

方式二:

通过类方法,后面会讲到

私有类属性

同对象的私有属性一样,类属性也有 私有 和 公有,上面定义的方式都是公有类属性。

方式一

私有类属性的前面有 两个下划线 _ _

注意:

  1. python解释器会对私有类属性做改名处理
  2. 私有类属性,不要在类外部使用,一般在 类方法中使用
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)

结果如下:

王
张

也就是 子类 动态添加 类属性

总结

  1. 类属性属于类,可以直接通过类访问和修改 类名.类属性
  2. 该类创建的对象也可以直接访问类属性,对象.类属性
  3. 在内存中只存在一个(该类的对象访问的类属性,是同一个)
  4. 私有类属性(开头两个下划线),不可以继承(本质还是可以继承,且做了改名处理)

原文出处:/show_1EF2Ed2yr5qx.html