## Notes on using __slots__ 

• When inheriting from a class without __slots__ , the __dict__ and __weakref__ attribute of the instances will always be accessible. 

• Without a __dict__ variable, instances cannot be assigned new variables not listed in the __slots__ definition. Attempts to assign to an unlisted variable name raises AttributeError . If dynamic assignment of new variables is desired, then add$_{'__dict__'}$ to the sequence of strings in the __slots__ declaration. 

• Without a __weakref__ variable for each instance, classes defining __slots__ do not support weak references to its instances. If weak reference support is needed, then add$_{'__weakref__'}$ to the sequence of strings in the __slots__ declaration. 

• __slots__ are implemented at the class level by creating descriptors ( Implementing Descriptors ) for each variable name. As a result, class attributes cannot be used to set default values for instance variables defined by __slots__ ; otherwise, the class attribute would overwrite the descriptor assignment. 

• The action of a __slots__ declaration is not limited to the class where it is defined. __slots__ declared in parents are available in child classes. However, child subclasses will get a __dict__ and __weakref__ unless they also define __slots__ (which should only contain names of any additional slots). 

• If a class defines a slot also defined in a base class, the instance variable defined by the base class slot is inaccessible (except by retrieving its descriptor directly from the base class). This renders the meaning of the program undefined. In the future, a check may be added to prevent this. 

• Nonempty __slots__ does not work for classes derived from “variable-length” built-in types such as $_{int}$, $_{bytes}$and$_{tuple}$ . 

• Any non-string iterable may be assigned to __slots__ . Mappings may also be used; however, in the future, special meaning may be assigned to the values corresponding to each key. 

• __class__ assignment works only if both classes have the same __slots__ . 

• Multiple inheritance with multiple slotted parent classes can be used, but only one parent is allowed to have attributes created by slots (the other bases must have empty slot layouts) - violations raise$_{TypeError}$. 

• If an iterator is used for __slots__ then a descriptor is created for each of the iterator’s values. However, the __slots__ attribute will be an empty iterator. 

## 3.3.3 Customizing class creation 

Whenever a class inherits from another class, __init_subclass__ is called on that class. This way, it is possible to write classes which change the behavior of subclasses. This is closely related to class decorators, but where class decorators only affect the specific class they’re applied to,$_{__init_subclass__}$ solely applies to future subclasses of the class defining the method. 

## classmethod object. __init_subclass__ ( cls$_{)}$ 

This method is called whenever the containing class is subclassed. cls is then the new subclass. If defined as a normal instance method, this method is implicitly converted to a class method. 

Keyword arguments which are given to a new class are passed to the parent’s class$_{__init_subclass__}$ . For compatibility with other classes using$_{__init_subclass__}$ , one should take out the needed keyword arguments and pass the others over to the base class, as in: 

classPhilosopher : def __init_subclass__ (cls,/, default_name, **kwargs): super() .__init_subclass__( **kwargs) cls.default_name=default_name classAustralianPhilosopher (Philosopher, default_name ="Bruce"): pass 

The default implementation$_{object.__init_subclass__}$ does nothing, but raises an error if it is called with any arguments. 

