(continued from previous page) 2. Helps create immutable objects where descriptors manage access to private attributes stored in$_{__slots__}$ : 17 4.6 Member objects and __slots__ When a class defines$_{__slots__}$ , it replaces instance dictionaries with a fixed-length array of slot values. From a user point of view that has several effects: 1. Provides immediate detection of bugs due to misspelled attribute assignments. Only attribute names specified in __slots__ are allowed: >>> auto =Vehicle() >>> auto.id_nubmer='VYE483814LQEX ' Traceback (most recent call last): ... AttributeError: 'Vehicle' object has no attribute 'id_nubmer' classVehicle : __slots__ =('id_number','make','model') >>> G .__doc__ "A doc for 'G'" classG : @classmethod @property def __doc__ (cls): return f'A doc for { cls.__name__ !r} ' The code path for$_{hasattr(type(self.f), '__get__')}$ was added in Python 3.9 and makes it possible for$_{classmethod()}$ to support chained decorators. For example, a classmethod and property could be chained together: Using the non-data descriptor protocol, a pure Python version of classmethod() would look like this: Now a new dictionary of unique keys can be constructed like this: d =cls() for key in iterable: d[key] =value return d >>> d =Dict.fromkeys('abracadabra') >>> type(d) is Dict True >>> d {'a': None, 'b': None, 'r': None, 'c': None, 'd': None} classClassMethod : "Emulate PyClassMethod_Type() in Objects/funcobject.c " def __init__ (self, f): self.f =f def __get__ (self, obj,cls= None ): if cls is None : cls=type(obj) if hasattr(type(self.f),'__get__ '): return self.f.__get__ (cls) return MethodType(self.f,cls)