Expert Python Programming(Third Edition)
上QQ阅读APP看书,第一时间看更新

Slots

An interesting feature that is very rarely used by developers is slots. They allow you to set a static attribute list for a given class with the __slots__ attribute, and skip the creation of the __dict__ dictionary in each instance of the class. They were intended to save memory space for classes with very few attributes, since __dict__ is not created at every instance.

Besides this, they can help to design classes whose signature needs to be frozen. For instance, if you need to restrict the dynamic features of the language over a class, defining slots can help:

>>> class Frozen:
...     __slots__ = ['ice', 'cream']
...     
>>> '__dict__' in dir(Frozen)
False
>>> 'ice' in dir(Frozen)
True
>>> frozen = Frozen()
>>> frozen.ice = True
>>> frozen.cream = None
>>> frozen.icy = True
Traceback (most recent call last): File "<input>", line 1, in <module> AttributeError: 'Frozen' object has no attribute 'icy'

This feature should be used carefully. When a set of available attributes is limited using __slots__, it is much harder to add something to the object dynamically. Some techniques, such as monkey patching, will not work with instances of classes that have slots defined. Fortunately, the new attributes can be added to the derived classes if they do not have their own slots defined:

>>> class Unfrozen(Frozen):
...     pass
...     
>>> unfrozen = Unfrozen()
>>> unfrozen.icy = False
>>> unfrozen.icy
False