《流畅的Python》 A Pythonic Object--第9章
Python的数据模型data model, 用户可以创建自定义类型,并且运行起来像内建类型一样自然。
即不是靠继承,而是duck typing。
- 支持用内建函数来创建可选的对象表现形式。例如repr(), bytes()等。object representation指的是用一个字符串来描述一个对象,例如:<__main__.Myclass object at 0x1040dc6d0>
Object Representations
Every object-oriented language has at least one standard way of ggetting a string representation from any object.
Python有2个:
- repr() : 开发者自查看的。背后是__repr__
- str(): 给用户看的。背后是__str__
使用__slots__类属性节省空间
类实例的__dict__方法,可以得到一个dict,里面储存了这个实例的所有属性,
如果有大量的实例,那么虽然使用__dict__调用属性速度提升了,但总的内存消耗变大。
__slots__
定义的属性,是类属性,如果类的实例只有少量属性,并且实例数量巨大,那么可以使用__slots__用类属性代替实例属性。
__slots__定义的类属性,不会储存在__dict__的字典内,因此节省了内存。
⚠️:
- 如果使用__slots__定义类属性,那么就不能使用实例属性。除非把__dict__也加入到类属性中。
- 类属性不能继承,因此每个子类都得定义自己的类属性。
例子:使用了__slots__,同时也把“__dict__”加入到类属性中,因此可以在__inti__()函数中传递male参数,作为实例属性。
class HauntedBus: __slots__ = ("age", "passengers", "__dict__") def __init__(self, male= True,passengers = None, age = 0): self.passengers = passengers self.age = age self.male = male def pick(self, name): self.passengers.append(name) bus1 = HauntedBus("tom",22) bus2 = HauntedBus("tony",11) print(bus1.__dict__) print(bus1.age)
注意:必须权衡利弊,明确需求,再使用__slots__。