• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1.. _descriptorhowto:
2
3======================
4Descriptor HowTo Guide
5======================
6
7:Author: Raymond Hettinger
8:Contact: <python at rcn dot com>
9
10.. Contents::
11
12
13:term:`Descriptors <descriptor>` let objects customize attribute lookup,
14storage, and deletion.
15
16This guide has four major sections:
17
181) The "primer" gives a basic overview, moving gently from simple examples,
19   adding one feature at a time.  Start here if you're new to descriptors.
20
212) The second section shows a complete, practical descriptor example.  If you
22   already know the basics, start there.
23
243) The third section provides a more technical tutorial that goes into the
25   detailed mechanics of how descriptors work.  Most people don't need this
26   level of detail.
27
284) The last section has pure Python equivalents for built-in descriptors that
29   are written in C.  Read this if you're curious about how functions turn
30   into bound methods or about the implementation of common tools like
31   :func:`classmethod`, :func:`staticmethod`, :func:`property`, and
32   :term:`__slots__`.
33
34
35Primer
36^^^^^^
37
38In this primer, we start with the most basic possible example and then we'll
39add new capabilities one by one.
40
41
42Simple example: A descriptor that returns a constant
43----------------------------------------------------
44
45The :class:`Ten` class is a descriptor that always returns the constant ``10``
46from its :meth:`__get__` method:
47
48.. testcode::
49
50    class Ten:
51        def __get__(self, obj, objtype=None):
52            return 10
53
54To use the descriptor, it must be stored as a class variable in another class:
55
56.. testcode::
57
58    class A:
59        x = 5                       # Regular class attribute
60        y = Ten()                   # Descriptor instance
61
62An interactive session shows the difference between normal attribute lookup
63and descriptor lookup:
64
65.. doctest::
66
67    >>> a = A()                     # Make an instance of class A
68    >>> a.x                         # Normal attribute lookup
69    5
70    >>> a.y                         # Descriptor lookup
71    10
72
73In the ``a.x`` attribute lookup, the dot operator finds the key ``x`` and the
74value ``5`` in the class dictionary.  In the ``a.y`` lookup, the dot operator
75finds a descriptor instance, recognized by its ``__get__`` method, and calls
76that method which returns ``10``.
77
78Note that the value ``10`` is not stored in either the class dictionary or the
79instance dictionary.  Instead, the value ``10`` is computed on demand.
80
81This example shows how a simple descriptor works, but it isn't very useful.
82For retrieving constants, normal attribute lookup would be better.
83
84In the next section, we'll create something more useful, a dynamic lookup.
85
86
87Dynamic lookups
88---------------
89
90Interesting descriptors typically run computations instead of returning
91constants:
92
93.. testcode::
94
95    import os
96
97    class DirectorySize:
98
99        def __get__(self, obj, objtype=None):
100            return len(os.listdir(obj.dirname))
101
102    class Directory:
103
104        size = DirectorySize()              # Descriptor instance
105
106        def __init__(self, dirname):
107            self.dirname = dirname          # Regular instance attribute
108
109An interactive session shows that the lookup is dynamic — it computes
110different, updated answers each time::
111
112    >>> s = Directory('songs')
113    >>> g = Directory('games')
114    >>> s.size                              # The songs directory has twenty files
115    20
116    >>> g.size                              # The games directory has three files
117    3
118    >>> open('games/newfile').close()       # Add a fourth file to the directory
119    >>> g.size                              # File count is automatically updated
120    4
121
122Besides showing how descriptors can run computations, this example also
123reveals the purpose of the parameters to :meth:`__get__`.  The *self*
124parameter is *size*, an instance of *DirectorySize*.  The *obj* parameter is
125either *g* or *s*, an instance of *Directory*.  It is the *obj* parameter that
126lets the :meth:`__get__` method learn the target directory.  The *objtype*
127parameter is the class *Directory*.
128
129
130Managed attributes
131------------------
132
133A popular use for descriptors is managing access to instance data.  The
134descriptor is assigned to a public attribute in the class dictionary while the
135actual data is stored as a private attribute in the instance dictionary.  The
136descriptor's :meth:`__get__` and :meth:`__set__` methods are triggered when
137the public attribute is accessed.
138
139In the following example, *age* is the public attribute and *_age* is the
140private attribute.  When the public attribute is accessed, the descriptor logs
141the lookup or update:
142
143.. testcode::
144
145    import logging
146
147    logging.basicConfig(level=logging.INFO)
148
149    class LoggedAgeAccess:
150
151        def __get__(self, obj, objtype=None):
152            value = obj._age
153            logging.info('Accessing %r giving %r', 'age', value)
154            return value
155
156        def __set__(self, obj, value):
157            logging.info('Updating %r to %r', 'age', value)
158            obj._age = value
159
160    class Person:
161
162        age = LoggedAgeAccess()             # Descriptor instance
163
164        def __init__(self, name, age):
165            self.name = name                # Regular instance attribute
166            self.age = age                  # Calls __set__()
167
168        def birthday(self):
169            self.age += 1                   # Calls both __get__() and __set__()
170
171
172An interactive session shows that all access to the managed attribute *age* is
173logged, but that the regular attribute *name* is not logged:
174
175.. testcode::
176    :hide:
177
178    import logging, sys
179    logging.basicConfig(level=logging.INFO, stream=sys.stdout, force=True)
180
181.. doctest::
182
183    >>> mary = Person('Mary M', 30)         # The initial age update is logged
184    INFO:root:Updating 'age' to 30
185    >>> dave = Person('David D', 40)
186    INFO:root:Updating 'age' to 40
187
188    >>> vars(mary)                          # The actual data is in a private attribute
189    {'name': 'Mary M', '_age': 30}
190    >>> vars(dave)
191    {'name': 'David D', '_age': 40}
192
193    >>> mary.age                            # Access the data and log the lookup
194    INFO:root:Accessing 'age' giving 30
195    30
196    >>> mary.birthday()                     # Updates are logged as well
197    INFO:root:Accessing 'age' giving 30
198    INFO:root:Updating 'age' to 31
199
200    >>> dave.name                           # Regular attribute lookup isn't logged
201    'David D'
202    >>> dave.age                            # Only the managed attribute is logged
203    INFO:root:Accessing 'age' giving 40
204    40
205
206One major issue with this example is that the private name *_age* is hardwired in
207the *LoggedAgeAccess* class.  That means that each instance can only have one
208logged attribute and that its name is unchangeable.  In the next example,
209we'll fix that problem.
210
211
212Customized names
213----------------
214
215When a class uses descriptors, it can inform each descriptor about which
216variable name was used.
217
218In this example, the :class:`Person` class has two descriptor instances,
219*name* and *age*.  When the :class:`Person` class is defined, it makes a
220callback to :meth:`__set_name__` in *LoggedAccess* so that the field names can
221be recorded, giving each descriptor its own *public_name* and *private_name*:
222
223.. testcode::
224
225    import logging
226
227    logging.basicConfig(level=logging.INFO)
228
229    class LoggedAccess:
230
231        def __set_name__(self, owner, name):
232            self.public_name = name
233            self.private_name = '_' + name
234
235        def __get__(self, obj, objtype=None):
236            value = getattr(obj, self.private_name)
237            logging.info('Accessing %r giving %r', self.public_name, value)
238            return value
239
240        def __set__(self, obj, value):
241            logging.info('Updating %r to %r', self.public_name, value)
242            setattr(obj, self.private_name, value)
243
244    class Person:
245
246        name = LoggedAccess()                # First descriptor instance
247        age = LoggedAccess()                 # Second descriptor instance
248
249        def __init__(self, name, age):
250            self.name = name                 # Calls the first descriptor
251            self.age = age                   # Calls the second descriptor
252
253        def birthday(self):
254            self.age += 1
255
256An interactive session shows that the :class:`Person` class has called
257:meth:`__set_name__` so that the field names would be recorded.  Here
258we call :func:`vars` to look up the descriptor without triggering it:
259
260.. doctest::
261
262    >>> vars(vars(Person)['name'])
263    {'public_name': 'name', 'private_name': '_name'}
264    >>> vars(vars(Person)['age'])
265    {'public_name': 'age', 'private_name': '_age'}
266
267The new class now logs access to both *name* and *age*:
268
269.. testcode::
270    :hide:
271
272    import logging, sys
273    logging.basicConfig(level=logging.INFO, stream=sys.stdout, force=True)
274
275.. doctest::
276
277    >>> pete = Person('Peter P', 10)
278    INFO:root:Updating 'name' to 'Peter P'
279    INFO:root:Updating 'age' to 10
280    >>> kate = Person('Catherine C', 20)
281    INFO:root:Updating 'name' to 'Catherine C'
282    INFO:root:Updating 'age' to 20
283
284The two *Person* instances contain only the private names::
285
286    >>> vars(pete)
287    {'_name': 'Peter P', '_age': 10}
288    >>> vars(kate)
289    {'_name': 'Catherine C', '_age': 20}
290
291
292Closing thoughts
293----------------
294
295A :term:`descriptor` is what we call any object that defines :meth:`__get__`,
296:meth:`__set__`, or :meth:`__delete__`.
297
298Optionally, descriptors can have a :meth:`__set_name__` method.  This is only
299used in cases where a descriptor needs to know either the class where it was
300created or the name of class variable it was assigned to.  (This method, if
301present, is called even if the class is not a descriptor.)
302
303Descriptors get invoked by the dot "operator" during attribute lookup.  If a
304descriptor is accessed indirectly with ``vars(some_class)[descriptor_name]``,
305the descriptor instance is returned without invoking it.
306
307Descriptors only work when used as class variables.  When put in instances,
308they have no effect.
309
310The main motivation for descriptors is to provide a hook allowing objects
311stored in class variables to control what happens during attribute lookup.
312
313Traditionally, the calling class controls what happens during lookup.
314Descriptors invert that relationship and allow the data being looked-up to
315have a say in the matter.
316
317Descriptors are used throughout the language.  It is how functions turn into
318bound methods.  Common tools like :func:`classmethod`, :func:`staticmethod`,
319:func:`property`, and :func:`functools.cached_property` are all implemented as
320descriptors.
321
322
323Complete Practical Example
324^^^^^^^^^^^^^^^^^^^^^^^^^^
325
326In this example, we create a practical and powerful tool for locating
327notoriously hard to find data corruption bugs.
328
329
330Validator class
331---------------
332
333A validator is a descriptor for managed attribute access.  Prior to storing
334any data, it verifies that the new value meets various type and range
335restrictions.  If those restrictions aren't met, it raises an exception to
336prevent data corruption at its source.
337
338This :class:`Validator` class is both an :term:`abstract base class` and a
339managed attribute descriptor:
340
341.. testcode::
342
343    from abc import ABC, abstractmethod
344
345    class Validator(ABC):
346
347        def __set_name__(self, owner, name):
348            self.private_name = '_' + name
349
350        def __get__(self, obj, objtype=None):
351            return getattr(obj, self.private_name)
352
353        def __set__(self, obj, value):
354            self.validate(value)
355            setattr(obj, self.private_name, value)
356
357        @abstractmethod
358        def validate(self, value):
359            pass
360
361Custom validators need to inherit from :class:`Validator` and must supply a
362:meth:`validate` method to test various restrictions as needed.
363
364
365Custom validators
366-----------------
367
368Here are three practical data validation utilities:
369
3701) :class:`OneOf` verifies that a value is one of a restricted set of options.
371
3722) :class:`Number` verifies that a value is either an :class:`int` or
373   :class:`float`.  Optionally, it verifies that a value is between a given
374   minimum or maximum.
375
3763) :class:`String` verifies that a value is a :class:`str`.  Optionally, it
377   validates a given minimum or maximum length.  It can validate a
378   user-defined `predicate
379   <https://en.wikipedia.org/wiki/Predicate_(mathematical_logic)>`_ as well.
380
381.. testcode::
382
383    class OneOf(Validator):
384
385        def __init__(self, *options):
386            self.options = set(options)
387
388        def validate(self, value):
389            if value not in self.options:
390                raise ValueError(f'Expected {value!r} to be one of {self.options!r}')
391
392    class Number(Validator):
393
394        def __init__(self, minvalue=None, maxvalue=None):
395            self.minvalue = minvalue
396            self.maxvalue = maxvalue
397
398        def validate(self, value):
399            if not isinstance(value, (int, float)):
400                raise TypeError(f'Expected {value!r} to be an int or float')
401            if self.minvalue is not None and value < self.minvalue:
402                raise ValueError(
403                    f'Expected {value!r} to be at least {self.minvalue!r}'
404                )
405            if self.maxvalue is not None and value > self.maxvalue:
406                raise ValueError(
407                    f'Expected {value!r} to be no more than {self.maxvalue!r}'
408                )
409
410    class String(Validator):
411
412        def __init__(self, minsize=None, maxsize=None, predicate=None):
413            self.minsize = minsize
414            self.maxsize = maxsize
415            self.predicate = predicate
416
417        def validate(self, value):
418            if not isinstance(value, str):
419                raise TypeError(f'Expected {value!r} to be an str')
420            if self.minsize is not None and len(value) < self.minsize:
421                raise ValueError(
422                    f'Expected {value!r} to be no smaller than {self.minsize!r}'
423                )
424            if self.maxsize is not None and len(value) > self.maxsize:
425                raise ValueError(
426                    f'Expected {value!r} to be no bigger than {self.maxsize!r}'
427                )
428            if self.predicate is not None and not self.predicate(value):
429                raise ValueError(
430                    f'Expected {self.predicate} to be true for {value!r}'
431                )
432
433
434Practical application
435---------------------
436
437Here's how the data validators can be used in a real class:
438
439.. testcode::
440
441    class Component:
442
443        name = String(minsize=3, maxsize=10, predicate=str.isupper)
444        kind = OneOf('wood', 'metal', 'plastic')
445        quantity = Number(minvalue=0)
446
447        def __init__(self, name, kind, quantity):
448            self.name = name
449            self.kind = kind
450            self.quantity = quantity
451
452The descriptors prevent invalid instances from being created:
453
454.. doctest::
455
456    >>> Component('Widget', 'metal', 5)      # Blocked: 'Widget' is not all uppercase
457    Traceback (most recent call last):
458        ...
459    ValueError: Expected <method 'isupper' of 'str' objects> to be true for 'Widget'
460
461    >>> Component('WIDGET', 'metle', 5)      # Blocked: 'metle' is misspelled
462    Traceback (most recent call last):
463        ...
464    ValueError: Expected 'metle' to be one of {'metal', 'plastic', 'wood'}
465
466    >>> Component('WIDGET', 'metal', -5)     # Blocked: -5 is negative
467    Traceback (most recent call last):
468        ...
469    ValueError: Expected -5 to be at least 0
470    >>> Component('WIDGET', 'metal', 'V')    # Blocked: 'V' isn't a number
471    Traceback (most recent call last):
472        ...
473    TypeError: Expected 'V' to be an int or float
474
475    >>> c = Component('WIDGET', 'metal', 5)  # Allowed:  The inputs are valid
476
477
478Technical Tutorial
479^^^^^^^^^^^^^^^^^^
480
481What follows is a more technical tutorial for the mechanics and details of how
482descriptors work.
483
484
485Abstract
486--------
487
488Defines descriptors, summarizes the protocol, and shows how descriptors are
489called.  Provides an example showing how object relational mappings work.
490
491Learning about descriptors not only provides access to a larger toolset, it
492creates a deeper understanding of how Python works.
493
494
495Definition and introduction
496---------------------------
497
498In general, a descriptor is an attribute value that has one of the methods in
499the descriptor protocol.  Those methods are :meth:`__get__`, :meth:`__set__`,
500and :meth:`__delete__`.  If any of those methods are defined for an
501attribute, it is said to be a :term:`descriptor`.
502
503The default behavior for attribute access is to get, set, or delete the
504attribute from an object's dictionary.  For instance, ``a.x`` has a lookup chain
505starting with ``a.__dict__['x']``, then ``type(a).__dict__['x']``, and
506continuing through the method resolution order of ``type(a)``. If the
507looked-up value is an object defining one of the descriptor methods, then Python
508may override the default behavior and invoke the descriptor method instead.
509Where this occurs in the precedence chain depends on which descriptor methods
510were defined.
511
512Descriptors are a powerful, general purpose protocol.  They are the mechanism
513behind properties, methods, static methods, class methods, and
514:func:`super()`.  They are used throughout Python itself.  Descriptors
515simplify the underlying C code and offer a flexible set of new tools for
516everyday Python programs.
517
518
519Descriptor protocol
520-------------------
521
522``descr.__get__(self, obj, type=None) -> value``
523
524``descr.__set__(self, obj, value) -> None``
525
526``descr.__delete__(self, obj) -> None``
527
528That is all there is to it.  Define any of these methods and an object is
529considered a descriptor and can override default behavior upon being looked up
530as an attribute.
531
532If an object defines :meth:`__set__` or :meth:`__delete__`, it is considered
533a data descriptor.  Descriptors that only define :meth:`__get__` are called
534non-data descriptors (they are often used for methods but other uses are
535possible).
536
537Data and non-data descriptors differ in how overrides are calculated with
538respect to entries in an instance's dictionary.  If an instance's dictionary
539has an entry with the same name as a data descriptor, the data descriptor
540takes precedence.  If an instance's dictionary has an entry with the same
541name as a non-data descriptor, the dictionary entry takes precedence.
542
543To make a read-only data descriptor, define both :meth:`__get__` and
544:meth:`__set__` with the :meth:`__set__` raising an :exc:`AttributeError` when
545called.  Defining the :meth:`__set__` method with an exception raising
546placeholder is enough to make it a data descriptor.
547
548
549Overview of descriptor invocation
550---------------------------------
551
552A descriptor can be called directly with ``desc.__get__(obj)`` or
553``desc.__get__(None, cls)``.
554
555But it is more common for a descriptor to be invoked automatically from
556attribute access.
557
558The expression ``obj.x`` looks up the attribute ``x`` in the chain of
559namespaces for ``obj``.  If the search finds a descriptor outside of the
560instance ``__dict__``, its :meth:`__get__` method is invoked according to the
561precedence rules listed below.
562
563The details of invocation depend on whether ``obj`` is an object, class, or
564instance of super.
565
566
567Invocation from an instance
568---------------------------
569
570Instance lookup scans through a chain of namespaces giving data descriptors
571the highest priority, followed by instance variables, then non-data
572descriptors, then class variables, and lastly :meth:`__getattr__` if it is
573provided.
574
575If a descriptor is found for ``a.x``, then it is invoked with:
576``desc.__get__(a, type(a))``.
577
578The logic for a dotted lookup is in :meth:`object.__getattribute__`.  Here is
579a pure Python equivalent:
580
581.. testcode::
582
583    def object_getattribute(obj, name):
584        "Emulate PyObject_GenericGetAttr() in Objects/object.c"
585        null = object()
586        objtype = type(obj)
587        cls_var = getattr(objtype, name, null)
588        descr_get = getattr(type(cls_var), '__get__', null)
589        if descr_get is not null:
590            if (hasattr(type(cls_var), '__set__')
591                or hasattr(type(cls_var), '__delete__')):
592                return descr_get(cls_var, obj, objtype)     # data descriptor
593        if hasattr(obj, '__dict__') and name in vars(obj):
594            return vars(obj)[name]                          # instance variable
595        if descr_get is not null:
596            return descr_get(cls_var, obj, objtype)         # non-data descriptor
597        if cls_var is not null:
598            return cls_var                                  # class variable
599        raise AttributeError(name)
600
601
602.. testcode::
603    :hide:
604
605    # Test the fidelity of object_getattribute() by comparing it with the
606    # normal object.__getattribute__().  The former will be accessed by
607    # square brackets and the latter by the dot operator.
608
609    class Object:
610
611        def __getitem__(obj, name):
612            try:
613                return object_getattribute(obj, name)
614            except AttributeError:
615                if not hasattr(type(obj), '__getattr__'):
616                    raise
617            return type(obj).__getattr__(obj, name)             # __getattr__
618
619    class DualOperator(Object):
620
621        x = 10
622
623        def __init__(self, z):
624            self.z = z
625
626        @property
627        def p2(self):
628            return 2 * self.x
629
630        @property
631        def p3(self):
632            return 3 * self.x
633
634        def m5(self, y):
635            return 5 * y
636
637        def m7(self, y):
638            return 7 * y
639
640        def __getattr__(self, name):
641            return ('getattr_hook', self, name)
642
643    class DualOperatorWithSlots:
644
645        __getitem__ = Object.__getitem__
646
647        __slots__ = ['z']
648
649        x = 15
650
651        def __init__(self, z):
652            self.z = z
653
654        @property
655        def p2(self):
656            return 2 * self.x
657
658        def m5(self, y):
659            return 5 * y
660
661        def __getattr__(self, name):
662            return ('getattr_hook', self, name)
663
664
665.. doctest::
666    :hide:
667
668    >>> a = DualOperator(11)
669    >>> vars(a).update(p3 = '_p3', m7 = '_m7')
670    >>> a.x == a['x'] == 10
671    True
672    >>> a.z == a['z'] == 11
673    True
674    >>> a.p2 == a['p2'] == 20
675    True
676    >>> a.p3 == a['p3'] == 30
677    True
678    >>> a.m5(100) == a.m5(100) == 500
679    True
680    >>> a.m7 == a['m7'] == '_m7'
681    True
682    >>> a.g == a['g'] == ('getattr_hook', a, 'g')
683    True
684
685    >>> b = DualOperatorWithSlots(22)
686    >>> b.x == b['x'] == 15
687    True
688    >>> b.z == b['z'] == 22
689    True
690    >>> b.p2 == b['p2'] == 30
691    True
692    >>> b.m5(200) == b['m5'](200) == 1000
693    True
694    >>> b.g == b['g'] == ('getattr_hook', b, 'g')
695    True
696
697
698Interestingly, attribute lookup doesn't call :meth:`object.__getattribute__`
699directly.  Instead, both the dot operator and the :func:`getattr` function
700perform attribute lookup by way of a helper function:
701
702.. testcode::
703
704    def getattr_hook(obj, name):
705        "Emulate slot_tp_getattr_hook() in Objects/typeobject.c"
706        try:
707            return obj.__getattribute__(name)
708        except AttributeError:
709            if not hasattr(type(obj), '__getattr__'):
710                raise
711        return type(obj).__getattr__(obj, name)             # __getattr__
712
713So if :meth:`__getattr__` exists, it is called whenever :meth:`__getattribute__`
714raises :exc:`AttributeError` (either directly or in one of the descriptor calls).
715
716Also, if a user calls :meth:`object.__getattribute__` directly, the
717:meth:`__getattr__` hook is bypassed entirely.
718
719
720Invocation from a class
721-----------------------
722
723The logic for a dotted lookup such as ``A.x`` is in
724:meth:`type.__getattribute__`.  The steps are similar to those for
725:meth:`object.__getattribute__` but the instance dictionary lookup is replaced
726by a search through the class's :term:`method resolution order`.
727
728If a descriptor is found, it is invoked with ``desc.__get__(None, A)``.
729
730The full C implementation can be found in :c:func:`type_getattro()` and
731:c:func:`_PyType_Lookup()` in :source:`Objects/typeobject.c`.
732
733
734Invocation from super
735---------------------
736
737The logic for super's dotted lookup is in the :meth:`__getattribute__` method for
738object returned by :class:`super()`.
739
740A dotted lookup such as ``super(A, obj).m`` searches ``obj.__class__.__mro__``
741for the base class ``B`` immediately following ``A`` and then returns
742``B.__dict__['m'].__get__(obj, A)``.  If not a descriptor, ``m`` is returned
743unchanged.
744
745The full C implementation can be found in :c:func:`super_getattro()` in
746:source:`Objects/typeobject.c`.  A pure Python equivalent can be found in
747`Guido's Tutorial
748<https://www.python.org/download/releases/2.2.3/descrintro/#cooperation>`_.
749
750
751Summary of invocation logic
752---------------------------
753
754The mechanism for descriptors is embedded in the :meth:`__getattribute__()`
755methods for :class:`object`, :class:`type`, and :func:`super`.
756
757The important points to remember are:
758
759* Descriptors are invoked by the :meth:`__getattribute__` method.
760
761* Classes inherit this machinery from :class:`object`, :class:`type`, or
762  :func:`super`.
763
764* Overriding :meth:`__getattribute__` prevents automatic descriptor calls
765  because all the descriptor logic is in that method.
766
767* :meth:`object.__getattribute__` and :meth:`type.__getattribute__` make
768  different calls to :meth:`__get__`.  The first includes the instance and may
769  include the class.  The second puts in ``None`` for the instance and always
770  includes the class.
771
772* Data descriptors always override instance dictionaries.
773
774* Non-data descriptors may be overridden by instance dictionaries.
775
776
777Automatic name notification
778---------------------------
779
780Sometimes it is desirable for a descriptor to know what class variable name it
781was assigned to.  When a new class is created, the :class:`type` metaclass
782scans the dictionary of the new class.  If any of the entries are descriptors
783and if they define :meth:`__set_name__`, that method is called with two
784arguments.  The *owner* is the class where the descriptor is used, and the
785*name* is the class variable the descriptor was assigned to.
786
787The implementation details are in :c:func:`type_new()` and
788:c:func:`set_names()` in :source:`Objects/typeobject.c`.
789
790Since the update logic is in :meth:`type.__new__`, notifications only take
791place at the time of class creation.  If descriptors are added to the class
792afterwards, :meth:`__set_name__` will need to be called manually.
793
794
795ORM example
796-----------
797
798The following code is simplified skeleton showing how data descriptors could
799be used to implement an `object relational mapping
800<https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping>`_.
801
802The essential idea is that the data is stored in an external database.  The
803Python instances only hold keys to the database's tables.  Descriptors take
804care of lookups or updates:
805
806.. testcode::
807
808    class Field:
809
810        def __set_name__(self, owner, name):
811            self.fetch = f'SELECT {name} FROM {owner.table} WHERE {owner.key}=?;'
812            self.store = f'UPDATE {owner.table} SET {name}=? WHERE {owner.key}=?;'
813
814        def __get__(self, obj, objtype=None):
815            return conn.execute(self.fetch, [obj.key]).fetchone()[0]
816
817        def __set__(self, obj, value):
818            conn.execute(self.store, [value, obj.key])
819            conn.commit()
820
821We can use the :class:`Field` class to define `models
822<https://en.wikipedia.org/wiki/Database_model>`_ that describe the schema for
823each table in a database:
824
825.. testcode::
826
827    class Movie:
828        table = 'Movies'                    # Table name
829        key = 'title'                       # Primary key
830        director = Field()
831        year = Field()
832
833        def __init__(self, key):
834            self.key = key
835
836    class Song:
837        table = 'Music'
838        key = 'title'
839        artist = Field()
840        year = Field()
841        genre = Field()
842
843        def __init__(self, key):
844            self.key = key
845
846To use the models, first connect to the database::
847
848    >>> import sqlite3
849    >>> conn = sqlite3.connect('entertainment.db')
850
851An interactive session shows how data is retrieved from the database and how
852it can be updated:
853
854.. testsetup::
855
856    song_data = [
857        ('Country Roads', 'John Denver', 1972),
858        ('Me and Bobby McGee', 'Janice Joplin', 1971),
859        ('Coal Miners Daughter', 'Loretta Lynn', 1970),
860    ]
861
862    movie_data = [
863        ('Star Wars', 'George Lucas', 1977),
864        ('Jaws', 'Steven Spielberg', 1975),
865        ('Aliens', 'James Cameron', 1986),
866    ]
867
868    import sqlite3
869
870    conn = sqlite3.connect(':memory:')
871    conn.execute('CREATE TABLE Music (title text, artist text, year integer);')
872    conn.execute('CREATE INDEX MusicNdx ON Music (title);')
873    conn.executemany('INSERT INTO Music VALUES (?, ?, ?);', song_data)
874    conn.execute('CREATE TABLE Movies (title text, director text, year integer);')
875    conn.execute('CREATE INDEX MovieNdx ON Music (title);')
876    conn.executemany('INSERT INTO Movies VALUES (?, ?, ?);', movie_data)
877    conn.commit()
878
879.. doctest::
880
881    >>> Movie('Star Wars').director
882    'George Lucas'
883    >>> jaws = Movie('Jaws')
884    >>> f'Released in {jaws.year} by {jaws.director}'
885    'Released in 1975 by Steven Spielberg'
886
887    >>> Song('Country Roads').artist
888    'John Denver'
889
890    >>> Movie('Star Wars').director = 'J.J. Abrams'
891    >>> Movie('Star Wars').director
892    'J.J. Abrams'
893
894
895Pure Python Equivalents
896^^^^^^^^^^^^^^^^^^^^^^^
897
898The descriptor protocol is simple and offers exciting possibilities.  Several
899use cases are so common that they have been prepackaged into built-in tools.
900Properties, bound methods, static methods, class methods, and \_\_slots\_\_ are
901all based on the descriptor protocol.
902
903
904Properties
905----------
906
907Calling :func:`property` is a succinct way of building a data descriptor that
908triggers a function call upon access to an attribute.  Its signature is::
909
910    property(fget=None, fset=None, fdel=None, doc=None) -> property
911
912The documentation shows a typical use to define a managed attribute ``x``:
913
914.. testcode::
915
916    class C:
917        def getx(self): return self.__x
918        def setx(self, value): self.__x = value
919        def delx(self): del self.__x
920        x = property(getx, setx, delx, "I'm the 'x' property.")
921
922To see how :func:`property` is implemented in terms of the descriptor protocol,
923here is a pure Python equivalent:
924
925.. testcode::
926
927    class Property:
928        "Emulate PyProperty_Type() in Objects/descrobject.c"
929
930        def __init__(self, fget=None, fset=None, fdel=None, doc=None):
931            self.fget = fget
932            self.fset = fset
933            self.fdel = fdel
934            if doc is None and fget is not None:
935                doc = fget.__doc__
936            self.__doc__ = doc
937
938        def __get__(self, obj, objtype=None):
939            if obj is None:
940                return self
941            if self.fget is None:
942                raise AttributeError("unreadable attribute")
943            return self.fget(obj)
944
945        def __set__(self, obj, value):
946            if self.fset is None:
947                raise AttributeError("can't set attribute")
948            self.fset(obj, value)
949
950        def __delete__(self, obj):
951            if self.fdel is None:
952                raise AttributeError("can't delete attribute")
953            self.fdel(obj)
954
955        def getter(self, fget):
956            return type(self)(fget, self.fset, self.fdel, self.__doc__)
957
958        def setter(self, fset):
959            return type(self)(self.fget, fset, self.fdel, self.__doc__)
960
961        def deleter(self, fdel):
962            return type(self)(self.fget, self.fset, fdel, self.__doc__)
963
964.. testcode::
965    :hide:
966
967    # Verify the Property() emulation
968
969    class CC:
970        def getx(self):
971            return self.__x
972        def setx(self, value):
973            self.__x = value
974        def delx(self):
975            del self.__x
976        x = Property(getx, setx, delx, "I'm the 'x' property.")
977
978    # Now do it again but use the decorator style
979
980    class CCC:
981        @Property
982        def x(self):
983            return self.__x
984        @x.setter
985        def x(self, value):
986            self.__x = value
987        @x.deleter
988        def x(self):
989            del self.__x
990
991
992.. doctest::
993    :hide:
994
995    >>> cc = CC()
996    >>> hasattr(cc, 'x')
997    False
998    >>> cc.x = 33
999    >>> cc.x
1000    33
1001    >>> del cc.x
1002    >>> hasattr(cc, 'x')
1003    False
1004
1005    >>> ccc = CCC()
1006    >>> hasattr(ccc, 'x')
1007    False
1008    >>> ccc.x = 333
1009    >>> ccc.x == 333
1010    True
1011    >>> del ccc.x
1012    >>> hasattr(ccc, 'x')
1013    False
1014
1015The :func:`property` builtin helps whenever a user interface has granted
1016attribute access and then subsequent changes require the intervention of a
1017method.
1018
1019For instance, a spreadsheet class may grant access to a cell value through
1020``Cell('b10').value``. Subsequent improvements to the program require the cell
1021to be recalculated on every access; however, the programmer does not want to
1022affect existing client code accessing the attribute directly.  The solution is
1023to wrap access to the value attribute in a property data descriptor:
1024
1025.. testcode::
1026
1027    class Cell:
1028        ...
1029
1030        @property
1031        def value(self):
1032            "Recalculate the cell before returning value"
1033            self.recalc()
1034            return self._value
1035
1036Either the built-in :func:`property` or our :func:`Property` equivalent would
1037work in this example.
1038
1039
1040Functions and methods
1041---------------------
1042
1043Python's object oriented features are built upon a function based environment.
1044Using non-data descriptors, the two are merged seamlessly.
1045
1046Functions stored in class dictionaries get turned into methods when invoked.
1047Methods only differ from regular functions in that the object instance is
1048prepended to the other arguments.  By convention, the instance is called
1049*self* but could be called *this* or any other variable name.
1050
1051Methods can be created manually with :class:`types.MethodType` which is
1052roughly equivalent to:
1053
1054.. testcode::
1055
1056    class MethodType:
1057        "Emulate Py_MethodType in Objects/classobject.c"
1058
1059        def __init__(self, func, obj):
1060            self.__func__ = func
1061            self.__self__ = obj
1062
1063        def __call__(self, *args, **kwargs):
1064            func = self.__func__
1065            obj = self.__self__
1066            return func(obj, *args, **kwargs)
1067
1068To support automatic creation of methods, functions include the
1069:meth:`__get__` method for binding methods during attribute access.  This
1070means that functions are non-data descriptors that return bound methods
1071during dotted lookup from an instance.  Here's how it works:
1072
1073.. testcode::
1074
1075    class Function:
1076        ...
1077
1078        def __get__(self, obj, objtype=None):
1079            "Simulate func_descr_get() in Objects/funcobject.c"
1080            if obj is None:
1081                return self
1082            return MethodType(self, obj)
1083
1084Running the following class in the interpreter shows how the function
1085descriptor works in practice:
1086
1087.. testcode::
1088
1089    class D:
1090        def f(self, x):
1091             return x
1092
1093The function has a :term:`qualified name` attribute to support introspection:
1094
1095.. doctest::
1096
1097    >>> D.f.__qualname__
1098    'D.f'
1099
1100Accessing the function through the class dictionary does not invoke
1101:meth:`__get__`.  Instead, it just returns the underlying function object::
1102
1103    >>> D.__dict__['f']
1104    <function D.f at 0x00C45070>
1105
1106Dotted access from a class calls :meth:`__get__` which just returns the
1107underlying function unchanged::
1108
1109    >>> D.f
1110    <function D.f at 0x00C45070>
1111
1112The interesting behavior occurs during dotted access from an instance.  The
1113dotted lookup calls :meth:`__get__` which returns a bound method object::
1114
1115    >>> d = D()
1116    >>> d.f
1117    <bound method D.f of <__main__.D object at 0x00B18C90>>
1118
1119Internally, the bound method stores the underlying function and the bound
1120instance::
1121
1122    >>> d.f.__func__
1123    <function D.f at 0x00C45070>
1124
1125    >>> d.f.__self__
1126    <__main__.D object at 0x1012e1f98>
1127
1128If you have ever wondered where *self* comes from in regular methods or where
1129*cls* comes from in class methods, this is it!
1130
1131
1132Static methods
1133--------------
1134
1135Non-data descriptors provide a simple mechanism for variations on the usual
1136patterns of binding functions into methods.
1137
1138To recap, functions have a :meth:`__get__` method so that they can be converted
1139to a method when accessed as attributes.  The non-data descriptor transforms an
1140``obj.f(*args)`` call into ``f(obj, *args)``.  Calling ``cls.f(*args)``
1141becomes ``f(*args)``.
1142
1143This chart summarizes the binding and its two most useful variants:
1144
1145      +-----------------+----------------------+------------------+
1146      | Transformation  | Called from an       | Called from a    |
1147      |                 | object               | class            |
1148      +=================+======================+==================+
1149      | function        | f(obj, \*args)       | f(\*args)        |
1150      +-----------------+----------------------+------------------+
1151      | staticmethod    | f(\*args)            | f(\*args)        |
1152      +-----------------+----------------------+------------------+
1153      | classmethod     | f(type(obj), \*args) | f(cls, \*args)   |
1154      +-----------------+----------------------+------------------+
1155
1156Static methods return the underlying function without changes.  Calling either
1157``c.f`` or ``C.f`` is the equivalent of a direct lookup into
1158``object.__getattribute__(c, "f")`` or ``object.__getattribute__(C, "f")``. As a
1159result, the function becomes identically accessible from either an object or a
1160class.
1161
1162Good candidates for static methods are methods that do not reference the
1163``self`` variable.
1164
1165For instance, a statistics package may include a container class for
1166experimental data.  The class provides normal methods for computing the average,
1167mean, median, and other descriptive statistics that depend on the data. However,
1168there may be useful functions which are conceptually related but do not depend
1169on the data.  For instance, ``erf(x)`` is handy conversion routine that comes up
1170in statistical work but does not directly depend on a particular dataset.
1171It can be called either from an object or the class:  ``s.erf(1.5) --> .9332`` or
1172``Sample.erf(1.5) --> .9332``.
1173
1174Since static methods return the underlying function with no changes, the
1175example calls are unexciting:
1176
1177.. testcode::
1178
1179    class E:
1180        @staticmethod
1181        def f(x):
1182            print(x)
1183
1184.. doctest::
1185
1186    >>> E.f(3)
1187    3
1188    >>> E().f(3)
1189    3
1190
1191Using the non-data descriptor protocol, a pure Python version of
1192:func:`staticmethod` would look like this:
1193
1194.. doctest::
1195
1196    class StaticMethod:
1197        "Emulate PyStaticMethod_Type() in Objects/funcobject.c"
1198
1199        def __init__(self, f):
1200            self.f = f
1201
1202        def __get__(self, obj, objtype=None):
1203            return self.f
1204
1205
1206Class methods
1207-------------
1208
1209Unlike static methods, class methods prepend the class reference to the
1210argument list before calling the function.  This format is the same
1211for whether the caller is an object or a class:
1212
1213.. testcode::
1214
1215    class F:
1216        @classmethod
1217        def f(cls, x):
1218            return cls.__name__, x
1219
1220.. doctest::
1221
1222    >>> F.f(3)
1223    ('F', 3)
1224    >>> F().f(3)
1225    ('F', 3)
1226
1227This behavior is useful whenever the method only needs to have a class
1228reference and does not rely on data stored in a specific instance.  One use for
1229class methods is to create alternate class constructors.  For example, the
1230classmethod :func:`dict.fromkeys` creates a new dictionary from a list of
1231keys.  The pure Python equivalent is:
1232
1233.. testcode::
1234
1235    class Dict(dict):
1236        @classmethod
1237        def fromkeys(cls, iterable, value=None):
1238            "Emulate dict_fromkeys() in Objects/dictobject.c"
1239            d = cls()
1240            for key in iterable:
1241                d[key] = value
1242            return d
1243
1244Now a new dictionary of unique keys can be constructed like this:
1245
1246.. doctest::
1247
1248    >>> d = Dict.fromkeys('abracadabra')
1249    >>> type(d) is Dict
1250    True
1251    >>> d
1252    {'a': None, 'b': None, 'r': None, 'c': None, 'd': None}
1253
1254Using the non-data descriptor protocol, a pure Python version of
1255:func:`classmethod` would look like this:
1256
1257.. testcode::
1258
1259    class ClassMethod:
1260        "Emulate PyClassMethod_Type() in Objects/funcobject.c"
1261
1262        def __init__(self, f):
1263            self.f = f
1264
1265        def __get__(self, obj, cls=None):
1266            if cls is None:
1267                cls = type(obj)
1268            if hasattr(obj, '__get__'):
1269                return self.f.__get__(cls)
1270            return MethodType(self.f, cls)
1271
1272.. testcode::
1273    :hide:
1274
1275    # Verify the emulation works
1276    class T:
1277        @ClassMethod
1278        def cm(cls, x, y):
1279            return (cls, x, y)
1280
1281.. doctest::
1282    :hide:
1283
1284    >>> T.cm(11, 22)
1285    (<class 'T'>, 11, 22)
1286
1287    # Also call it from an instance
1288    >>> t = T()
1289    >>> t.cm(11, 22)
1290    (<class 'T'>, 11, 22)
1291
1292The code path for ``hasattr(obj, '__get__')`` was added in Python 3.9 and
1293makes it possible for :func:`classmethod` to support chained decorators.
1294For example, a classmethod and property could be chained together:
1295
1296.. testcode::
1297
1298    class G:
1299        @classmethod
1300        @property
1301        def __doc__(cls):
1302            return f'A doc for {cls.__name__!r}'
1303
1304.. doctest::
1305
1306    >>> G.__doc__
1307    "A doc for 'G'"
1308
1309
1310Member objects and __slots__
1311----------------------------
1312
1313When a class defines ``__slots__``, it replaces instance dictionaries with a
1314fixed-length array of slot values.  From a user point of view that has
1315several effects:
1316
13171. Provides immediate detection of bugs due to misspelled attribute
1318assignments.  Only attribute names specified in ``__slots__`` are allowed:
1319
1320.. testcode::
1321
1322        class Vehicle:
1323            __slots__ = ('id_number', 'make', 'model')
1324
1325.. doctest::
1326
1327        >>> auto = Vehicle()
1328        >>> auto.id_nubmer = 'VYE483814LQEX'
1329        Traceback (most recent call last):
1330            ...
1331        AttributeError: 'Vehicle' object has no attribute 'id_nubmer'
1332
13332. Helps create immutable objects where descriptors manage access to private
1334attributes stored in ``__slots__``:
1335
1336.. testcode::
1337
1338    class Immutable:
1339
1340        __slots__ = ('_dept', '_name')          # Replace the instance dictionary
1341
1342        def __init__(self, dept, name):
1343            self._dept = dept                   # Store to private attribute
1344            self._name = name                   # Store to private attribute
1345
1346        @property                               # Read-only descriptor
1347        def dept(self):
1348            return self._dept
1349
1350        @property
1351        def name(self):                         # Read-only descriptor
1352            return self._name
1353
1354.. doctest::
1355
1356    >>> mark = Immutable('Botany', 'Mark Watney')
1357    >>> mark.dept
1358    'Botany'
1359    >>> mark.dept = 'Space Pirate'
1360    Traceback (most recent call last):
1361        ...
1362    AttributeError: can't set attribute
1363    >>> mark.location = 'Mars'
1364    Traceback (most recent call last):
1365        ...
1366    AttributeError: 'Immutable' object has no attribute 'location'
1367
13683. Saves memory.  On a 64-bit Linux build, an instance with two attributes
1369takes 48 bytes with ``__slots__`` and 152 bytes without.  This `flyweight
1370design pattern <https://en.wikipedia.org/wiki/Flyweight_pattern>`_ likely only
1371matters when a large number of instances are going to be created.
1372
13734. Blocks tools like :func:`functools.cached_property` which require an
1374instance dictionary to function correctly:
1375
1376.. testcode::
1377
1378    from functools import cached_property
1379
1380    class CP:
1381        __slots__ = ()                          # Eliminates the instance dict
1382
1383        @cached_property                        # Requires an instance dict
1384        def pi(self):
1385            return 4 * sum((-1.0)**n / (2.0*n + 1.0)
1386                           for n in reversed(range(100_000)))
1387
1388.. doctest::
1389
1390    >>> CP().pi
1391    Traceback (most recent call last):
1392      ...
1393    TypeError: No '__dict__' attribute on 'CP' instance to cache 'pi' property.
1394
1395It is not possible to create an exact drop-in pure Python version of
1396``__slots__`` because it requires direct access to C structures and control
1397over object memory allocation.  However, we can build a mostly faithful
1398simulation where the actual C structure for slots is emulated by a private
1399``_slotvalues`` list.  Reads and writes to that private structure are managed
1400by member descriptors:
1401
1402.. testcode::
1403
1404    null = object()
1405
1406    class Member:
1407
1408        def __init__(self, name, clsname, offset):
1409            'Emulate PyMemberDef in Include/structmember.h'
1410            # Also see descr_new() in Objects/descrobject.c
1411            self.name = name
1412            self.clsname = clsname
1413            self.offset = offset
1414
1415        def __get__(self, obj, objtype=None):
1416            'Emulate member_get() in Objects/descrobject.c'
1417            # Also see PyMember_GetOne() in Python/structmember.c
1418            value = obj._slotvalues[self.offset]
1419            if value is null:
1420                raise AttributeError(self.name)
1421            return value
1422
1423        def __set__(self, obj, value):
1424            'Emulate member_set() in Objects/descrobject.c'
1425            obj._slotvalues[self.offset] = value
1426
1427        def __delete__(self, obj):
1428            'Emulate member_delete() in Objects/descrobject.c'
1429            value = obj._slotvalues[self.offset]
1430            if value is null:
1431                raise AttributeError(self.name)
1432            obj._slotvalues[self.offset] = null
1433
1434        def __repr__(self):
1435            'Emulate member_repr() in Objects/descrobject.c'
1436            return f'<Member {self.name!r} of {self.clsname!r}>'
1437
1438The :meth:`type.__new__` method takes care of adding member objects to class
1439variables:
1440
1441.. testcode::
1442
1443    class Type(type):
1444        'Simulate how the type metaclass adds member objects for slots'
1445
1446        def __new__(mcls, clsname, bases, mapping):
1447            'Emuluate type_new() in Objects/typeobject.c'
1448            # type_new() calls PyTypeReady() which calls add_methods()
1449            slot_names = mapping.get('slot_names', [])
1450            for offset, name in enumerate(slot_names):
1451                mapping[name] = Member(name, clsname, offset)
1452            return type.__new__(mcls, clsname, bases, mapping)
1453
1454The :meth:`object.__new__` method takes care of creating instances that have
1455slots instead of an instance dictionary.  Here is a rough simulation in pure
1456Python:
1457
1458.. testcode::
1459
1460    class Object:
1461        'Simulate how object.__new__() allocates memory for __slots__'
1462
1463        def __new__(cls, *args):
1464            'Emulate object_new() in Objects/typeobject.c'
1465            inst = super().__new__(cls)
1466            if hasattr(cls, 'slot_names'):
1467                empty_slots = [null] * len(cls.slot_names)
1468                object.__setattr__(inst, '_slotvalues', empty_slots)
1469            return inst
1470
1471        def __setattr__(self, name, value):
1472            'Emulate _PyObject_GenericSetAttrWithDict() Objects/object.c'
1473            cls = type(self)
1474            if hasattr(cls, 'slot_names') and name not in cls.slot_names:
1475                raise AttributeError(
1476                    f'{type(self).__name__!r} object has no attribute {name!r}'
1477                )
1478            super().__setattr__(name, value)
1479
1480        def __delattr__(self, name):
1481            'Emulate _PyObject_GenericSetAttrWithDict() Objects/object.c'
1482            cls = type(self)
1483            if hasattr(cls, 'slot_names') and name not in cls.slot_names:
1484                raise AttributeError(
1485                    f'{type(self).__name__!r} object has no attribute {name!r}'
1486                )
1487            super().__delattr__(name)
1488
1489To use the simulation in a real class, just inherit from :class:`Object` and
1490set the :term:`metaclass` to :class:`Type`:
1491
1492.. testcode::
1493
1494    class H(Object, metaclass=Type):
1495        'Instance variables stored in slots'
1496
1497        slot_names = ['x', 'y']
1498
1499        def __init__(self, x, y):
1500            self.x = x
1501            self.y = y
1502
1503At this point, the metaclass has loaded member objects for *x* and *y*::
1504
1505    >>> from pprint import pp
1506    >>> pp(dict(vars(H)))
1507    {'__module__': '__main__',
1508     '__doc__': 'Instance variables stored in slots',
1509     'slot_names': ['x', 'y'],
1510     '__init__': <function H.__init__ at 0x7fb5d302f9d0>,
1511     'x': <Member 'x' of 'H'>,
1512     'y': <Member 'y' of 'H'>}
1513
1514.. doctest::
1515    :hide:
1516
1517    # We test this separately because the preceding section is not
1518    # doctestable due to the hex memory address for the __init__ function
1519    >>> isinstance(vars(H)['x'], Member)
1520    True
1521    >>> isinstance(vars(H)['y'], Member)
1522    True
1523
1524When instances are created, they have a ``slot_values`` list where the
1525attributes are stored:
1526
1527.. doctest::
1528
1529    >>> h = H(10, 20)
1530    >>> vars(h)
1531    {'_slotvalues': [10, 20]}
1532    >>> h.x = 55
1533    >>> vars(h)
1534    {'_slotvalues': [55, 20]}
1535
1536Misspelled or unassigned attributes will raise an exception:
1537
1538.. doctest::
1539
1540    >>> h.xz
1541    Traceback (most recent call last):
1542        ...
1543    AttributeError: 'H' object has no attribute 'xz'
1544
1545.. doctest::
1546   :hide:
1547
1548    # Examples for deleted attributes are not shown because this section
1549    # is already a bit lengthy.  We still test that code here.
1550    >>> del h.x
1551    >>> hasattr(h, 'x')
1552    False
1553
1554    # Also test the code for uninitialized slots
1555    >>> class HU(Object, metaclass=Type):
1556    ...     slot_names = ['x', 'y']
1557    ...
1558    >>> hu = HU()
1559    >>> hasattr(hu, 'x')
1560    False
1561    >>> hasattr(hu, 'y')
1562    False
1563