类的属性
在 Python 中,数据属性和处理数据的方法统称为属性(attribute),方法也可称为方法属性,本质上是可调用的(callable)属性。Python 提供了丰富的 API 用于控制访问属性,以及实现动态属性。即使访问不存在的属性,也可以通过特殊方法实现“虚拟属性”,从而即时计算属性的值。
处理属性的特殊属性
为了方便处理属性,Python 定义了一些特殊属性,包括:
__class__:对象所属类的引用。obj.__class__与type(obj)效果一致。类和类的实例都具有属性,有些属性只能在类中查询,比如特殊方法;__dict__:存储类或实例的可写属性的字典。如果设置了__slots__属性,实例可能没有__dict__属性;__slots__:类可以定义这个属性,限制实例能拥有哪些属性。该属性的值可以是个可迭代对象,但通常会使用元组。如果类设置了__slots__属性且__slots__中不包含'__dict__',那么该类的实例没有__dict__属性。
__dict__
默认情况下,Python 会使用名为 __dict__ 的字典存储类和实例中的可写属性。其中,类属性字典由名为 mappingproxy 的代理对象包装,mappingproxy 定义在 collections.abc 模块中,特别指代类属性字典的类型:mappingproxy = type(type.__dict__)。类属性字典包含显式定义在类中的字段和方法,以及一些可写的特殊属性,包括模块、字典、弱引用和文档字符串。
1 | class Foo: |
类属性不仅限于类字典中所展示的,还包含一些不可变的类属性,比如所属类的引用 __class__,直接父类组成的元组 __bases__ 等。
实例属性字典则是普通的字典类型,为实例属性赋值,会动态的修改实例字典。如果属性不存在,则将其添加到字典中,包括在初始化方法 __init__ 中赋值的实例属性。