绝对不要使用两个前导下划线, 这是很烦人的自私行为。
9.1 对象表示形式
每门面向对象的语言至少都有一种获取对象的字符串表示形式的标准方式。 Python 提供了两种方式。
repr( )
以便于开发者理解的方式返回对象的字符串表示形式。
str( )
以便于用户理解的方式返回对象的字符串表示形式。
9.8 使用__slots__
类属性节省空间
默认情况下, Python 在各个实例中名为 __dict__
的字典里存储实例属性。 为了使用底层的散列表提升访问速度, 字典会消耗大量内存。 如果要处理数百万个属性不多的实例, 通过 __slots__
类属性, 能节省大量内存, 方法是让解释器在元组中存储实例属性, 而不用字典。
class Vector2d:
__slots__ = ('__x', '__y')
typecode = 'd'
在类中定义__slots__
属性的目的是告诉解释器: “这个类中的所有实
例属性都在这儿了! ”这样, Python 会在各个实例中使用类似元组的结构存储实例变量, 从而避免使用消耗内存的 __dict__
属性。 如果有数百万个实例同时活动, 这样做能节省大量内存。
__slots__
的问题
总之, 如果使用得当, __slots__
能显著节省内存, 不过有几点要注
意。
- 每个子类都要定义
__slots__
属性, 因为解释器会忽略继承的
__slots__
属性。 - 实例只能拥有
__slots__
中列出的属性, 除非把'__dict__'
加
入__slots__
中( 这样做就失去了节省内存的功效) 。 - 如果不把
'__weakref__'
加入__slots__
, 实例就不能作为弱引用的目标
9.10 本章小结
简洁胜于复杂
要构建符合 Python 风格的对象, 就要观察真正的 Python 对象的行
为。