blob: f1d1ab1d1d6101d75a39da6542476249bd1b75c3 [file] [log] [blame]
Raymond Hettinger8d3d7312020-10-23 12:55:39 -07001.. _descriptorhowto:
2
Georg Brandl45cceeb2010-05-19 21:39:51 +00003======================
4Descriptor HowTo Guide
5======================
6
7:Author: Raymond Hettinger
8:Contact: <python at rcn dot com>
9
10.. Contents::
11
Raymond Hettinger8d3d7312020-10-23 12:55:39 -070012
13:term:`Descriptors <descriptor>` let objects customize attribute lookup,
14storage, and deletion.
15
Raymond Hettingere6a7ea42020-10-25 07:12:50 -070016This guide has four major sections:
Raymond Hettinger8d3d7312020-10-23 12:55:39 -070017
181) The "primer" gives a basic overview, moving gently from simple examples,
19 adding one feature at a time. It is a great place to start.
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
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700284) 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 how to implement common tools like
31 :func:`classmethod`, :func:`staticmethod`, and :func:`property`.
32
Raymond Hettinger8d3d7312020-10-23 12:55:39 -070033
34Primer
35^^^^^^
36
Raymond Hettinger4a9c6372020-10-24 20:34:39 -070037In this primer, we start with the most basic possible example and then we'll
38add new capabilities one by one.
Raymond Hettinger8d3d7312020-10-23 12:55:39 -070039
40
41Simple example: A descriptor that returns a constant
42----------------------------------------------------
43
44The :class:`Ten` class is a descriptor that always returns the constant ``10``::
45
46
47 class Ten:
48 def __get__(self, obj, objtype=None):
49 return 10
50
51To use the descriptor, it must be stored as a class variable in another class::
52
53 class A:
54 x = 5 # Regular class attribute
55 y = Ten() # Descriptor
56
57An interactive session shows the difference between normal attribute lookup
58and descriptor lookup::
59
60 >>> a = A() # Make an instance of class A
61 >>> a.x # Normal attribute lookup
62 5
63 >>> a.y # Descriptor lookup
64 10
65
66In the ``a.x`` attribute lookup, the dot operator finds the value ``5`` stored
67in the class dictionary. In the ``a.y`` descriptor lookup, the dot operator
68calls the descriptor's :meth:`__get__()` method. That method returns ``10``.
69Note that the value ``10`` is not stored in either the class dictionary or the
70instance dictionary. Instead, the value ``10`` is computed on demand.
71
72This example shows how a simple descriptor works, but it isn't very useful.
73For retrieving constants, normal attribute lookup would be better.
74
75In the next section, we'll create something more useful, a dynamic lookup.
76
77
78Dynamic lookups
79---------------
80
81Interesting descriptors typically run computations instead of doing lookups::
82
83
84 import os
85
86 class DirectorySize:
87
88 def __get__(self, obj, objtype=None):
89 return len(os.listdir(obj.dirname))
90
91 class Directory:
92
93 size = DirectorySize() # Descriptor
94
95 def __init__(self, dirname):
96 self.dirname = dirname # Regular instance attribute
97
98An interactive session shows that the lookup is dynamic — it computes
99different, updated answers each time::
100
101 >>> g = Directory('games')
102 >>> s = Directory('songs')
103 >>> g.size # The games directory has three files
104 3
105 >>> os.system('touch games/newfile') # Add a fourth file to the directory
106 0
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700107 >>> g.size # Automatically updated
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700108 4
109 >>> s.size # The songs directory has twenty files
110 20
111
112Besides showing how descriptors can run computations, this example also
113reveals the purpose of the parameters to :meth:`__get__`. The *self*
114parameter is *size*, an instance of *DirectorySize*. The *obj* parameter is
115either *g* or *s*, an instance of *Directory*. It is *obj* parameter that
116lets the :meth:`__get__` method learn the target directory. The *objtype*
117parameter is the class *Directory*.
118
119
120Managed attributes
121------------------
122
123A popular use for descriptors is managing access to instance data. The
124descriptor is assigned to a public attribute in the class dictionary while the
125actual data is stored as a private attribute in the instance dictionary. The
126descriptor's :meth:`__get__` and :meth:`__set__` methods are triggered when
127the public attribute is accessed.
128
129In the following example, *age* is the public attribute and *_age* is the
130private attribute. When the public attribute is accessed, the descriptor logs
131the lookup or update::
132
133 import logging
134
135 logging.basicConfig(level=logging.INFO)
136
137 class LoggedAgeAccess:
138
139 def __get__(self, obj, objtype=None):
140 value = obj._age
141 logging.info('Accessing %r giving %r', 'age', value)
142 return value
143
144 def __set__(self, obj, value):
145 logging.info('Updating %r to %r', 'age', value)
146 obj._age = value
147
148 class Person:
149
150 age = LoggedAgeAccess() # Descriptor
151
152 def __init__(self, name, age):
153 self.name = name # Regular instance attribute
154 self.age = age # Calls the descriptor
155
156 def birthday(self):
157 self.age += 1 # Calls both __get__() and __set__()
158
159
160An interactive session shows that all access to the managed attribute *age* is
161logged, but that the regular attribute *name* is not logged::
162
163 >>> mary = Person('Mary M', 30) # The initial age update is logged
164 INFO:root:Updating 'age' to 30
165 >>> dave = Person('David D', 40)
166 INFO:root:Updating 'age' to 40
167
168 >>> vars(mary) # The actual data is in a private attribute
169 {'name': 'Mary M', '_age': 30}
170 >>> vars(dave)
171 {'name': 'David D', '_age': 40}
172
173 >>> mary.age # Access the data and log the lookup
174 INFO:root:Accessing 'age' giving 30
175 30
176 >>> mary.birthday() # Updates are logged as well
177 INFO:root:Accessing 'age' giving 30
178 INFO:root:Updating 'age' to 31
179
180 >>> dave.name # Regular attribute lookup isn't logged
181 'David D'
182 >>> dave.age # Only the managed attribute is logged
183 INFO:root:Accessing 'age' giving 40
184 40
185
186One major issue with this example is the private name *_age* is hardwired in
187the *LoggedAgeAccess* class. That means that each instance can only have one
188logged attribute and that its name is unchangeable. In the next example,
189we'll fix that problem.
190
191
192Customized Names
193----------------
194
195When a class uses descriptors, it can inform each descriptor about what
196variable name was used.
197
198In this example, the :class:`Person` class has two descriptor instances,
199*name* and *age*. When the :class:`Person` class is defined, it makes a
200callback to :meth:`__set_name__` in *LoggedAccess* so that the field names can
201be recorded, giving each descriptor its own *public_name* and *private_name*::
202
203 import logging
204
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700205 logging.basicConfig(level=logging.INFO)
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700206
207 class LoggedAccess:
208
209 def __set_name__(self, owner, name):
210 self.public_name = name
211 self.private_name = f'_{name}'
212
213 def __get__(self, obj, objtype=None):
214 value = getattr(obj, self.private_name)
215 logging.info('Accessing %r giving %r', self.public_name, value)
216 return value
217
218 def __set__(self, obj, value):
219 logging.info('Updating %r to %r', self.public_name, value)
220 setattr(obj, self.private_name, value)
221
222 class Person:
223
224 name = LoggedAccess() # First descriptor
225 age = LoggedAccess() # Second descriptor
226
227 def __init__(self, name, age):
228 self.name = name # Calls the first descriptor
229 self.age = age # Calls the second descriptor
230
231 def birthday(self):
232 self.age += 1
233
234An interactive session shows that the :class:`Person` class has called
235:meth:`__set_name__` so that the field names would be recorded. Here
236we call :func:`vars` to lookup the descriptor without triggering it::
237
238 >>> vars(vars(Person)['name'])
239 {'public_name': 'name', 'private_name': '_name'}
240 >>> vars(vars(Person)['age'])
241 {'public_name': 'age', 'private_name': '_age'}
242
243The new class now logs access to both *name* and *age*::
244
245 >>> pete = Person('Peter P', 10)
246 INFO:root:Updating 'name' to 'Peter P'
247 INFO:root:Updating 'age' to 10
248 >>> kate = Person('Catherine C', 20)
249 INFO:root:Updating 'name' to 'Catherine C'
250 INFO:root:Updating 'age' to 20
251
252The two *Person* instances contain only the private names::
253
254 >>> vars(pete)
255 {'_name': 'Peter P', '_age': 10}
256 >>> vars(kate)
257 {'_name': 'Catherine C', '_age': 20}
258
259
260Closing thoughts
261----------------
262
263A :term:`descriptor` is what we call any object that defines :meth:`__get__`,
264:meth:`__set__`, or :meth:`__delete__`.
265
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700266Optionally, descriptors can have a :meth:`__set_name__` method. This is only
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700267used in cases where a descriptor needs to know either the class where it was
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700268created or the name of class variable it was assigned to.
269
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700270Descriptors get invoked by the dot operator during attribute lookup. If a
271descriptor is accessed indirectly with ``vars(some_class)[descriptor_name]``,
272the descriptor instance is returned without invoking it.
273
274Descriptors only work when used as class variables. When put in instances,
275they have no effect.
276
277The main motivation for descriptors is to provide a hook allowing objects
278stored in class variables to control what happens during dotted lookup.
279
280Traditionally, the calling class controls what happens during lookup.
281Descriptors invert that relationship and allow the data being looked-up to
282have a say in the matter.
283
284Descriptors are used throughout the language. It is how functions turn into
285bound methods. Common tools like :func:`classmethod`, :func:`staticmethod`,
286:func:`property`, and :func:`functools.cached_property` are all implemented as
287descriptors.
288
289
290Complete Practical Example
291^^^^^^^^^^^^^^^^^^^^^^^^^^
292
293In this example, we create a practical and powerful tool for locating
294notoriously hard to find data corruption bugs.
295
296
297Validator class
298---------------
299
300A validator is a descriptor for managed attribute access. Prior to storing
301any data, it verifies that the new value meets various type and range
302restrictions. If those restrictions aren't met, it raises an exception to
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700303prevent data corruption at its source.
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700304
305This :class:`Validator` class is both an :term:`abstract base class` and a
306managed attribute descriptor::
307
308 from abc import ABC, abstractmethod
309
310 class Validator(ABC):
311
312 def __set_name__(self, owner, name):
313 self.private_name = f'_{name}'
314
315 def __get__(self, obj, objtype=None):
316 return getattr(obj, self.private_name)
317
318 def __set__(self, obj, value):
319 self.validate(value)
320 setattr(obj, self.private_name, value)
321
322 @abstractmethod
323 def validate(self, value):
324 pass
325
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700326Custom validators need to inherit from :class:`Validator` and must supply a
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700327:meth:`validate` method to test various restrictions as needed.
328
329
330Custom validators
331-----------------
332
333Here are three practical data validation utilities:
334
3351) :class:`OneOf` verifies that a value is one of a restricted set of options.
336
3372) :class:`Number` verifies that a value is either an :class:`int` or
338 :class:`float`. Optionally, it verifies that a value is between a given
339 minimum or maximum.
340
3413) :class:`String` verifies that a value is a :class:`str`. Optionally, it
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700342 validates a given minimum or maximum length. It can validate a
343 user-defined `predicate
344 <https://en.wikipedia.org/wiki/Predicate_(mathematical_logic)>`_ as well.
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700345
346::
347
348 class OneOf(Validator):
349
350 def __init__(self, *options):
351 self.options = set(options)
352
353 def validate(self, value):
354 if value not in self.options:
355 raise ValueError(f'Expected {value!r} to be one of {self.options!r}')
356
357 class Number(Validator):
358
359 def __init__(self, minvalue=None, maxvalue=None):
360 self.minvalue = minvalue
361 self.maxvalue = maxvalue
362
363 def validate(self, value):
364 if not isinstance(value, (int, float)):
365 raise TypeError(f'Expected {value!r} to be an int or float')
366 if self.minvalue is not None and value < self.minvalue:
367 raise ValueError(
368 f'Expected {value!r} to be at least {self.minvalue!r}'
369 )
370 if self.maxvalue is not None and value > self.maxvalue:
371 raise ValueError(
372 f'Expected {value!r} to be no more than {self.maxvalue!r}'
373 )
374
375 class String(Validator):
376
377 def __init__(self, minsize=None, maxsize=None, predicate=None):
378 self.minsize = minsize
379 self.maxsize = maxsize
380 self.predicate = predicate
381
382 def validate(self, value):
383 if not isinstance(value, str):
384 raise TypeError(f'Expected {value!r} to be an str')
385 if self.minsize is not None and len(value) < self.minsize:
386 raise ValueError(
387 f'Expected {value!r} to be no smaller than {self.minsize!r}'
388 )
389 if self.maxsize is not None and len(value) > self.maxsize:
390 raise ValueError(
391 f'Expected {value!r} to be no bigger than {self.maxsize!r}'
392 )
393 if self.predicate is not None and not self.predicate(value):
394 raise ValueError(
395 f'Expected {self.predicate} to be true for {value!r}'
396 )
397
398
399Practical use
400-------------
401
402Here's how the data validators can be used in a real class::
403
404 class Component:
405
406 name = String(minsize=3, maxsize=10, predicate=str.isupper)
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700407 kind = OneOf('wood', 'metal', 'plastic')
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700408 quantity = Number(minvalue=0)
409
410 def __init__(self, name, kind, quantity):
411 self.name = name
412 self.kind = kind
413 self.quantity = quantity
414
415The descriptors prevent invalid instances from being created::
416
417 Component('WIDGET', 'metal', 5) # Allowed.
418 Component('Widget', 'metal', 5) # Blocked: 'Widget' is not all uppercase
419 Component('WIDGET', 'metle', 5) # Blocked: 'metle' is misspelled
420 Component('WIDGET', 'metal', -5) # Blocked: -5 is negative
421 Component('WIDGET', 'metal', 'V') # Blocked: 'V' isn't a number
422
423
424Technical Tutorial
425^^^^^^^^^^^^^^^^^^
426
427What follows is a more technical tutorial for the mechanics and details of how
428descriptors work.
429
430
Georg Brandl45cceeb2010-05-19 21:39:51 +0000431Abstract
432--------
433
434Defines descriptors, summarizes the protocol, and shows how descriptors are
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700435called. Provides an example showing how object relational mappings work.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000436
437Learning about descriptors not only provides access to a larger toolset, it
438creates a deeper understanding of how Python works and an appreciation for the
439elegance of its design.
440
441
442Definition and Introduction
443---------------------------
444
445In general, a descriptor is an object attribute with "binding behavior", one
446whose attribute access has been overridden by methods in the descriptor
447protocol. Those methods are :meth:`__get__`, :meth:`__set__`, and
448:meth:`__delete__`. If any of those methods are defined for an object, it is
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700449said to be a :term:`descriptor`.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000450
451The default behavior for attribute access is to get, set, or delete the
452attribute from an object's dictionary. For instance, ``a.x`` has a lookup chain
453starting with ``a.__dict__['x']``, then ``type(a).__dict__['x']``, and
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700454continuing through the base classes of ``type(a)``. If the
Georg Brandl45cceeb2010-05-19 21:39:51 +0000455looked-up value is an object defining one of the descriptor methods, then Python
456may override the default behavior and invoke the descriptor method instead.
457Where this occurs in the precedence chain depends on which descriptor methods
Florent Xiclunaaa6c1d22011-12-12 18:54:29 +0100458were defined.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000459
460Descriptors are a powerful, general purpose protocol. They are the mechanism
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700461behind properties, methods, static methods, class methods, and
462:func:`super()`. They are used throughout Python itself. Descriptors
463simplify the underlying C code and offer a flexible set of new tools for
464everyday Python programs.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000465
466
467Descriptor Protocol
468-------------------
469
NotAFile28ea4c22018-09-10 23:35:38 +0200470``descr.__get__(self, obj, type=None) -> value``
Georg Brandl45cceeb2010-05-19 21:39:51 +0000471
NotAFile28ea4c22018-09-10 23:35:38 +0200472``descr.__set__(self, obj, value) -> None``
Georg Brandl45cceeb2010-05-19 21:39:51 +0000473
NotAFile28ea4c22018-09-10 23:35:38 +0200474``descr.__delete__(self, obj) -> None``
Georg Brandl45cceeb2010-05-19 21:39:51 +0000475
476That is all there is to it. Define any of these methods and an object is
477considered a descriptor and can override default behavior upon being looked up
478as an attribute.
479
Aaron Hall, MBA4054b172018-05-20 19:46:42 -0400480If an object defines :meth:`__set__` or :meth:`__delete__`, it is considered
Georg Brandl45cceeb2010-05-19 21:39:51 +0000481a data descriptor. Descriptors that only define :meth:`__get__` are called
482non-data descriptors (they are typically used for methods but other uses are
483possible).
484
485Data and non-data descriptors differ in how overrides are calculated with
486respect to entries in an instance's dictionary. If an instance's dictionary
487has an entry with the same name as a data descriptor, the data descriptor
488takes precedence. If an instance's dictionary has an entry with the same
489name as a non-data descriptor, the dictionary entry takes precedence.
490
491To make a read-only data descriptor, define both :meth:`__get__` and
492:meth:`__set__` with the :meth:`__set__` raising an :exc:`AttributeError` when
493called. Defining the :meth:`__set__` method with an exception raising
494placeholder is enough to make it a data descriptor.
495
496
497Invoking Descriptors
498--------------------
499
500A descriptor can be called directly by its method name. For example,
501``d.__get__(obj)``.
502
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700503But it is more common for a descriptor to be invoked automatically from
504attribute access. The expression ``obj.d`` looks up ``d`` in the dictionary of
505``obj``. If ``d`` defines the method :meth:`__get__`, then ``d.__get__(obj)``
Georg Brandl45cceeb2010-05-19 21:39:51 +0000506is invoked according to the precedence rules listed below.
507
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700508The details of invocation depend on whether ``obj`` is an object, class, or
509instance of super.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000510
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700511**Objects**: The machinery is in :meth:`object.__getattribute__`.
512
513It transforms ``b.x`` into ``type(b).__dict__['x'].__get__(b, type(b))``.
514
515The implementation works through a precedence chain that gives data descriptors
Georg Brandl45cceeb2010-05-19 21:39:51 +0000516priority over instance variables, instance variables priority over non-data
Benjamin Peterson57fb11b2014-10-06 21:10:25 -0400517descriptors, and assigns lowest priority to :meth:`__getattr__` if provided.
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700518
Benjamin Peterson57fb11b2014-10-06 21:10:25 -0400519The full C implementation can be found in :c:func:`PyObject_GenericGetAttr()` in
520:source:`Objects/object.c`.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000521
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700522**Classes**: The machinery is in :meth:`type.__getattribute__`.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000523
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700524It transforms ``A.x`` into ``A.__dict__['x'].__get__(None, A)``.
525
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700526The full C implementation can be found in :c:func:`type_getattro()` in
527:source:`Objects/typeobject.c`.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000528
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700529**Super**: The machinery is in the custom :meth:`__getattribute__` method for
530object returned by :class:`super()`.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000531
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700532The attribute lookup ``super(A, obj).m`` searches ``obj.__class__.__mro__`` for
533the base class ``B`` immediately following ``A`` and then returns
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700534``B.__dict__['m'].__get__(obj, A)``. If not a descriptor, ``m`` is returned
535unchanged. If not in the dictionary, ``m`` reverts to a search using
536:meth:`object.__getattribute__`.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000537
Florent Xiclunaaa6c1d22011-12-12 18:54:29 +0100538The implementation details are in :c:func:`super_getattro()` in
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700539:source:`Objects/typeobject.c`. A pure Python equivalent can be found in
Benjamin Peterson57fb11b2014-10-06 21:10:25 -0400540`Guido's Tutorial`_.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000541
Georg Brandl9bdcb3b2014-10-29 09:37:43 +0100542.. _`Guido's Tutorial`: https://www.python.org/download/releases/2.2.3/descrintro/#cooperation
Georg Brandl45cceeb2010-05-19 21:39:51 +0000543
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700544**Summary**: The mechanism for descriptors is embedded in the
545:meth:`__getattribute__()` methods for :class:`object`, :class:`type`, and
546:func:`super`.
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700547
548The important points to remember are:
549
550* Descriptors are invoked by the :meth:`__getattribute__` method.
551
552* Classes inherit this machinery from :class:`object`, :class:`type`, or
553 :func:`super`.
554
555* Overriding :meth:`__getattribute__` prevents automatic descriptor calls
556 because all the descriptor logic is in that method.
557
558* :meth:`object.__getattribute__` and :meth:`type.__getattribute__` make
559 different calls to :meth:`__get__`. The first includes the instance and may
560 include the class. The second puts in ``None`` for the instance and always
561 includes the class.
562
563* Data descriptors always override instance dictionaries.
564
565* Non-data descriptors may be overridden by instance dictionaries.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000566
567
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700568Automatic Name Notification
569---------------------------
570
571Sometimes it is desirable for a descriptor to know what class variable name it
572was assigned to. When a new class is created, the :class:`type` metaclass
573scans the dictionary of the new class. If any of the entries are descriptors
574and if they define :meth:`__set_name__`, that method is called with two
575arguments. The *owner* is the class where the descriptor is used, the *name*
576is class variable the descriptor was assigned to.
577
578The implementation details are in :c:func:`type_new()` and
579:c:func:`set_names()` in :source:`Objects/typeobject.c`.
580
581Since the update logic is in :meth:`type.__new__`, notifications only take
582place at the time of class creation. If descriptors are added to the class
583afterwards, :meth:`__set_name__` will need to be called manually.
584
585
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700586ORM Example
587-----------
Georg Brandl45cceeb2010-05-19 21:39:51 +0000588
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700589The following code is simplified skeleton showing how data descriptors could
590be used to implement an `object relational mapping
591<https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping>`_.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000592
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700593The essential idea is that the data is stored in an external database. The
594Python instances only hold keys to the database's tables. Descriptors take
595care of lookups or updates::
Georg Brandl45cceeb2010-05-19 21:39:51 +0000596
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700597 class Field:
598
599 def __set_name__(self, owner, name):
600 self.fetch = f'SELECT {name} FROM {owner.table} WHERE {owner.key}=?;'
601 self.store = f'UPDATE {owner.table} SET {name}=? WHERE {owner.key}=?;'
Georg Brandl45cceeb2010-05-19 21:39:51 +0000602
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700603 def __get__(self, obj, objtype=None):
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700604 return conn.execute(self.fetch, [obj.key]).fetchone()[0]
Georg Brandl45cceeb2010-05-19 21:39:51 +0000605
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700606 def __set__(self, obj, value):
607 conn.execute(self.store, [value, obj.key])
608 conn.commit()
Georg Brandl45cceeb2010-05-19 21:39:51 +0000609
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700610We can use the :class:`Field` class to define "models" that describe the schema
611for each table in a database::
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700612
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700613 class Movie:
614 table = 'Movies' # Table name
615 key = 'title' # Primary key
616 director = Field()
617 year = Field()
Georg Brandl45cceeb2010-05-19 21:39:51 +0000618
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700619 def __init__(self, key):
620 self.key = key
621
622 class Song:
623 table = 'Music'
624 key = 'title'
625 artist = Field()
626 year = Field()
627 genre = Field()
628
629 def __init__(self, key):
630 self.key = key
631
632An interactive session shows how data is retrieved from the database and how
633it can be updated::
634
635 >>> import sqlite3
636 >>> conn = sqlite3.connect('entertainment.db')
637
638 >>> Movie('Star Wars').director
639 'George Lucas'
640 >>> jaws = Movie('Jaws')
641 >>> f'Released in {jaws.year} by {jaws.director}'
642 'Released in 1975 by Steven Spielberg'
643
644 >>> Song('Country Roads').artist
645 'John Denver'
646
647 >>> Movie('Star Wars').director = 'J.J. Abrams'
648 >>> Movie('Star Wars').director
649 'J.J. Abrams'
650
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700651Pure Python Equivalents
652^^^^^^^^^^^^^^^^^^^^^^^
653
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700654The descriptor protocol is simple and offers exciting possibilities. Several
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700655use cases are so common that they have been prepackaged into builtin tools.
656Properties, bound methods, static methods, and class methods are all based on
657the descriptor protocol.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000658
659
660Properties
661----------
662
663Calling :func:`property` is a succinct way of building a data descriptor that
664triggers function calls upon access to an attribute. Its signature is::
665
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700666 property(fget=None, fset=None, fdel=None, doc=None) -> property
Georg Brandl45cceeb2010-05-19 21:39:51 +0000667
668The documentation shows a typical use to define a managed attribute ``x``::
669
Serhiy Storchakae042a452019-06-10 13:35:52 +0300670 class C:
Georg Brandl45cceeb2010-05-19 21:39:51 +0000671 def getx(self): return self.__x
672 def setx(self, value): self.__x = value
673 def delx(self): del self.__x
674 x = property(getx, setx, delx, "I'm the 'x' property.")
675
676To see how :func:`property` is implemented in terms of the descriptor protocol,
677here is a pure Python equivalent::
678
Serhiy Storchakae042a452019-06-10 13:35:52 +0300679 class Property:
Georg Brandl45cceeb2010-05-19 21:39:51 +0000680 "Emulate PyProperty_Type() in Objects/descrobject.c"
681
682 def __init__(self, fget=None, fset=None, fdel=None, doc=None):
683 self.fget = fget
684 self.fset = fset
685 self.fdel = fdel
Raymond Hettinger632c8c82013-03-10 09:41:18 -0700686 if doc is None and fget is not None:
687 doc = fget.__doc__
Georg Brandl45cceeb2010-05-19 21:39:51 +0000688 self.__doc__ = doc
689
690 def __get__(self, obj, objtype=None):
691 if obj is None:
692 return self
693 if self.fget is None:
Raymond Hettinger632c8c82013-03-10 09:41:18 -0700694 raise AttributeError("unreadable attribute")
Georg Brandl45cceeb2010-05-19 21:39:51 +0000695 return self.fget(obj)
696
697 def __set__(self, obj, value):
698 if self.fset is None:
Raymond Hettinger632c8c82013-03-10 09:41:18 -0700699 raise AttributeError("can't set attribute")
Georg Brandl45cceeb2010-05-19 21:39:51 +0000700 self.fset(obj, value)
701
702 def __delete__(self, obj):
703 if self.fdel is None:
Raymond Hettinger632c8c82013-03-10 09:41:18 -0700704 raise AttributeError("can't delete attribute")
Georg Brandl45cceeb2010-05-19 21:39:51 +0000705 self.fdel(obj)
706
Raymond Hettinger632c8c82013-03-10 09:41:18 -0700707 def getter(self, fget):
708 return type(self)(fget, self.fset, self.fdel, self.__doc__)
709
710 def setter(self, fset):
711 return type(self)(self.fget, fset, self.fdel, self.__doc__)
712
713 def deleter(self, fdel):
714 return type(self)(self.fget, self.fset, fdel, self.__doc__)
715
Georg Brandl45cceeb2010-05-19 21:39:51 +0000716The :func:`property` builtin helps whenever a user interface has granted
717attribute access and then subsequent changes require the intervention of a
718method.
719
720For instance, a spreadsheet class may grant access to a cell value through
721``Cell('b10').value``. Subsequent improvements to the program require the cell
722to be recalculated on every access; however, the programmer does not want to
723affect existing client code accessing the attribute directly. The solution is
724to wrap access to the value attribute in a property data descriptor::
725
Serhiy Storchakae042a452019-06-10 13:35:52 +0300726 class Cell:
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700727 ...
728
729 @property
730 def value(self):
_ = NaNb066edf2017-06-23 11:54:35 +0800731 "Recalculate the cell before returning value"
Georg Brandl45cceeb2010-05-19 21:39:51 +0000732 self.recalc()
_ = NaNb066edf2017-06-23 11:54:35 +0800733 return self._value
Georg Brandl45cceeb2010-05-19 21:39:51 +0000734
735
736Functions and Methods
737---------------------
738
739Python's object oriented features are built upon a function based environment.
740Using non-data descriptors, the two are merged seamlessly.
741
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700742Functions stored in class dictionaries get turned into methods when invoked.
743Methods only differ from regular functions in that the object instance is
744prepended to the other arguments. By convention, the instance is called
745*self* but could be called *this* or any other variable name.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000746
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700747Methods can be created manually with :class:`types.MethodType` which is
748roughly equivalent to::
749
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700750 class MethodType:
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700751 "Emulate Py_MethodType in Objects/classobject.c"
752
753 def __init__(self, func, obj):
754 self.__func__ = func
755 self.__self__ = obj
756
757 def __call__(self, *args, **kwargs):
758 func = self.__func__
759 obj = self.__self__
760 return func(obj, *args, **kwargs)
761
762To support automatic creation of methods, functions include the
763:meth:`__get__` method for binding methods during attribute access. This
764means that functions are non-data descriptors which return bound methods
765during dotted lookup from an instance. Here's how it works::
Georg Brandl45cceeb2010-05-19 21:39:51 +0000766
Serhiy Storchakae042a452019-06-10 13:35:52 +0300767 class Function:
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700768 ...
769
Georg Brandl45cceeb2010-05-19 21:39:51 +0000770 def __get__(self, obj, objtype=None):
771 "Simulate func_descr_get() in Objects/funcobject.c"
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700772 if obj is None:
773 return self
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700774 return MethodType(self, obj)
Georg Brandl45cceeb2010-05-19 21:39:51 +0000775
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700776Running the following class in the interpreter shows how the function
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700777descriptor works in practice::
Georg Brandl45cceeb2010-05-19 21:39:51 +0000778
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700779 class D:
780 def f(self, x):
781 return x
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700782
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700783The function has a :term:`qualified name` attribute to support introspection::
784
785 >>> D.f.__qualname__
786 'D.f'
787
788Accessing the function through the class dictionary does not invoke
789:meth:`__get__`. Instead, it just returns the underlying function object::
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700790
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700791 >>> D.__dict__['f']
792 <function D.f at 0x00C45070>
793
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700794Dotted access from a class calls :meth:`__get__` which just returns the
795underlying function unchanged::
796
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700797 >>> D.f
798 <function D.f at 0x00C45070>
799
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700800The interesting behavior occurs during dotted access from an instance. The
801dotted lookup calls :meth:`__get__` which returns a bound method object::
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700802
803 >>> d = D()
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700804 >>> d.f
Georg Brandl45cceeb2010-05-19 21:39:51 +0000805 <bound method D.f of <__main__.D object at 0x00B18C90>>
806
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700807Internally, the bound method stores the underlying function and the bound
808instance::
809
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700810 >>> d.f.__func__
811 <function D.f at 0x1012e5ae8>
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700812
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700813 >>> d.f.__self__
814 <__main__.D object at 0x1012e1f98>
Georg Brandl45cceeb2010-05-19 21:39:51 +0000815
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700816If you have ever wondered where *self* comes from in regular methods or where
817*cls* comes from in class methods, this is it!
818
Georg Brandl45cceeb2010-05-19 21:39:51 +0000819
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700820Static Methods
821--------------
Georg Brandl45cceeb2010-05-19 21:39:51 +0000822
823Non-data descriptors provide a simple mechanism for variations on the usual
824patterns of binding functions into methods.
825
826To recap, functions have a :meth:`__get__` method so that they can be converted
Serhiy Storchakad65c9492015-11-02 14:10:23 +0200827to a method when accessed as attributes. The non-data descriptor transforms an
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700828``obj.f(*args)`` call into ``f(obj, *args)``. Calling ``cls.f(*args)``
Georg Brandl45cceeb2010-05-19 21:39:51 +0000829becomes ``f(*args)``.
830
831This chart summarizes the binding and its two most useful variants:
832
833 +-----------------+----------------------+------------------+
834 | Transformation | Called from an | Called from a |
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700835 | | object | class |
Georg Brandl45cceeb2010-05-19 21:39:51 +0000836 +=================+======================+==================+
837 | function | f(obj, \*args) | f(\*args) |
838 +-----------------+----------------------+------------------+
839 | staticmethod | f(\*args) | f(\*args) |
840 +-----------------+----------------------+------------------+
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700841 | classmethod | f(type(obj), \*args) | f(cls, \*args) |
Georg Brandl45cceeb2010-05-19 21:39:51 +0000842 +-----------------+----------------------+------------------+
843
844Static methods return the underlying function without changes. Calling either
845``c.f`` or ``C.f`` is the equivalent of a direct lookup into
846``object.__getattribute__(c, "f")`` or ``object.__getattribute__(C, "f")``. As a
847result, the function becomes identically accessible from either an object or a
848class.
849
850Good candidates for static methods are methods that do not reference the
851``self`` variable.
852
853For instance, a statistics package may include a container class for
854experimental data. The class provides normal methods for computing the average,
855mean, median, and other descriptive statistics that depend on the data. However,
856there may be useful functions which are conceptually related but do not depend
857on the data. For instance, ``erf(x)`` is handy conversion routine that comes up
858in statistical work but does not directly depend on a particular dataset.
859It can be called either from an object or the class: ``s.erf(1.5) --> .9332`` or
860``Sample.erf(1.5) --> .9332``.
861
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700862Since static methods return the underlying function with no changes, the
863example calls are unexciting::
Georg Brandl45cceeb2010-05-19 21:39:51 +0000864
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700865 class E:
866 @staticmethod
867 def f(x):
868 print(x)
869
Shubham Aggarwalabbdd1f2019-03-20 08:25:55 +0530870 >>> E.f(3)
Georg Brandl45cceeb2010-05-19 21:39:51 +0000871 3
Shubham Aggarwalabbdd1f2019-03-20 08:25:55 +0530872 >>> E().f(3)
Georg Brandl45cceeb2010-05-19 21:39:51 +0000873 3
874
875Using the non-data descriptor protocol, a pure Python version of
876:func:`staticmethod` would look like this::
877
Serhiy Storchakae042a452019-06-10 13:35:52 +0300878 class StaticMethod:
Serhiy Storchakadba90392016-05-10 12:01:23 +0300879 "Emulate PyStaticMethod_Type() in Objects/funcobject.c"
Georg Brandl45cceeb2010-05-19 21:39:51 +0000880
Serhiy Storchakadba90392016-05-10 12:01:23 +0300881 def __init__(self, f):
882 self.f = f
Georg Brandl45cceeb2010-05-19 21:39:51 +0000883
Serhiy Storchakadba90392016-05-10 12:01:23 +0300884 def __get__(self, obj, objtype=None):
885 return self.f
Georg Brandl45cceeb2010-05-19 21:39:51 +0000886
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700887
888Class Methods
889-------------
890
Georg Brandl45cceeb2010-05-19 21:39:51 +0000891Unlike static methods, class methods prepend the class reference to the
892argument list before calling the function. This format is the same
893for whether the caller is an object or a class::
894
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700895 class F:
896 @classmethod
897 def f(cls, x):
898 return cls.__name__, x
899
900 >>> print(F.f(3))
901 ('F', 3)
902 >>> print(F().f(3))
903 ('F', 3)
Georg Brandl45cceeb2010-05-19 21:39:51 +0000904
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700905This behavior is useful whenever the method only needs to have a class
906reference and does rely on data stored in a specific instance. One use for
907class methods is to create alternate class constructors. For example, the
908classmethod :func:`dict.fromkeys` creates a new dictionary from a list of
909keys. The pure Python equivalent is::
Georg Brandl45cceeb2010-05-19 21:39:51 +0000910
Serhiy Storchakae042a452019-06-10 13:35:52 +0300911 class Dict:
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700912 ...
913
914 @classmethod
915 def fromkeys(cls, iterable, value=None):
Georg Brandl45cceeb2010-05-19 21:39:51 +0000916 "Emulate dict_fromkeys() in Objects/dictobject.c"
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700917 d = cls()
Georg Brandl45cceeb2010-05-19 21:39:51 +0000918 for key in iterable:
919 d[key] = value
920 return d
Georg Brandl45cceeb2010-05-19 21:39:51 +0000921
922Now a new dictionary of unique keys can be constructed like this::
923
924 >>> Dict.fromkeys('abracadabra')
925 {'a': None, 'r': None, 'b': None, 'c': None, 'd': None}
926
927Using the non-data descriptor protocol, a pure Python version of
928:func:`classmethod` would look like this::
929
Serhiy Storchakae042a452019-06-10 13:35:52 +0300930 class ClassMethod:
Serhiy Storchakadba90392016-05-10 12:01:23 +0300931 "Emulate PyClassMethod_Type() in Objects/funcobject.c"
Georg Brandl45cceeb2010-05-19 21:39:51 +0000932
Serhiy Storchakadba90392016-05-10 12:01:23 +0300933 def __init__(self, f):
934 self.f = f
Georg Brandl45cceeb2010-05-19 21:39:51 +0000935
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700936 def __get__(self, obj, cls=None):
937 if cls is None:
938 cls = type(obj)
Raymond Hettinger8e5b0fd2020-10-23 18:37:27 -0700939 if hasattr(obj, '__get__'):
940 return self.f.__get__(cls)
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700941 return MethodType(self.f, cls)
Raymond Hettinger8e5b0fd2020-10-23 18:37:27 -0700942
943The code path for ``hasattr(obj, '__get__')`` was added in Python 3.9 and
944makes it possible for :func:`classmethod` to support chained decorators.
945For example, a classmethod and property could be chained together::
946
947 class G:
948 @classmethod
949 @property
950 def __doc__(cls):
951 return f'A doc for {cls.__name__!r}'