类的属性
在 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__
中赋值的实例属性。