blob: 5de6d32f22f906caa7ff1b6890488c7a1d66ec2e [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
Raymond Hettinger148c76b2020-11-01 09:10:06 -080055 y = Ten() # Descriptor instance
Raymond Hettinger8d3d7312020-10-23 12:55:39 -070056
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
Raymond Hettinger8d3d7312020-10-23 12:55:39 -070083 import os
84
85 class DirectorySize:
86
87 def __get__(self, obj, objtype=None):
88 return len(os.listdir(obj.dirname))
89
90 class Directory:
91
Raymond Hettinger148c76b2020-11-01 09:10:06 -080092 size = DirectorySize() # Descriptor instance
Raymond Hettinger8d3d7312020-10-23 12:55:39 -070093
94 def __init__(self, dirname):
95 self.dirname = dirname # Regular instance attribute
96
97An interactive session shows that the lookup is dynamic — it computes
98different, updated answers each time::
99
100 >>> g = Directory('games')
101 >>> s = Directory('songs')
102 >>> g.size # The games directory has three files
103 3
104 >>> os.system('touch games/newfile') # Add a fourth file to the directory
105 0
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700106 >>> g.size # Automatically updated
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700107 4
108 >>> s.size # The songs directory has twenty files
109 20
110
111Besides showing how descriptors can run computations, this example also
112reveals the purpose of the parameters to :meth:`__get__`. The *self*
113parameter is *size*, an instance of *DirectorySize*. The *obj* parameter is
114either *g* or *s*, an instance of *Directory*. It is *obj* parameter that
115lets the :meth:`__get__` method learn the target directory. The *objtype*
116parameter is the class *Directory*.
117
118
119Managed attributes
120------------------
121
122A popular use for descriptors is managing access to instance data. The
123descriptor is assigned to a public attribute in the class dictionary while the
124actual data is stored as a private attribute in the instance dictionary. The
125descriptor's :meth:`__get__` and :meth:`__set__` methods are triggered when
126the public attribute is accessed.
127
128In the following example, *age* is the public attribute and *_age* is the
129private attribute. When the public attribute is accessed, the descriptor logs
130the lookup or update::
131
132 import logging
133
134 logging.basicConfig(level=logging.INFO)
135
136 class LoggedAgeAccess:
137
138 def __get__(self, obj, objtype=None):
139 value = obj._age
140 logging.info('Accessing %r giving %r', 'age', value)
141 return value
142
143 def __set__(self, obj, value):
144 logging.info('Updating %r to %r', 'age', value)
145 obj._age = value
146
147 class Person:
148
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800149 age = LoggedAgeAccess() # Descriptor instance
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700150
151 def __init__(self, name, age):
152 self.name = name # Regular instance attribute
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800153 self.age = age # Calls __set__()
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700154
155 def birthday(self):
156 self.age += 1 # Calls both __get__() and __set__()
157
158
159An interactive session shows that all access to the managed attribute *age* is
160logged, but that the regular attribute *name* is not logged::
161
162 >>> mary = Person('Mary M', 30) # The initial age update is logged
163 INFO:root:Updating 'age' to 30
164 >>> dave = Person('David D', 40)
165 INFO:root:Updating 'age' to 40
166
167 >>> vars(mary) # The actual data is in a private attribute
168 {'name': 'Mary M', '_age': 30}
169 >>> vars(dave)
170 {'name': 'David D', '_age': 40}
171
172 >>> mary.age # Access the data and log the lookup
173 INFO:root:Accessing 'age' giving 30
174 30
175 >>> mary.birthday() # Updates are logged as well
176 INFO:root:Accessing 'age' giving 30
177 INFO:root:Updating 'age' to 31
178
179 >>> dave.name # Regular attribute lookup isn't logged
180 'David D'
181 >>> dave.age # Only the managed attribute is logged
182 INFO:root:Accessing 'age' giving 40
183 40
184
185One major issue with this example is the private name *_age* is hardwired in
186the *LoggedAgeAccess* class. That means that each instance can only have one
187logged attribute and that its name is unchangeable. In the next example,
188we'll fix that problem.
189
190
191Customized Names
192----------------
193
194When a class uses descriptors, it can inform each descriptor about what
195variable name was used.
196
197In this example, the :class:`Person` class has two descriptor instances,
198*name* and *age*. When the :class:`Person` class is defined, it makes a
199callback to :meth:`__set_name__` in *LoggedAccess* so that the field names can
200be recorded, giving each descriptor its own *public_name* and *private_name*::
201
202 import logging
203
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700204 logging.basicConfig(level=logging.INFO)
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700205
206 class LoggedAccess:
207
208 def __set_name__(self, owner, name):
209 self.public_name = name
210 self.private_name = f'_{name}'
211
212 def __get__(self, obj, objtype=None):
213 value = getattr(obj, self.private_name)
214 logging.info('Accessing %r giving %r', self.public_name, value)
215 return value
216
217 def __set__(self, obj, value):
218 logging.info('Updating %r to %r', self.public_name, value)
219 setattr(obj, self.private_name, value)
220
221 class Person:
222
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800223 name = LoggedAccess() # First descriptor instance
224 age = LoggedAccess() # Second descriptor instance
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700225
226 def __init__(self, name, age):
227 self.name = name # Calls the first descriptor
228 self.age = age # Calls the second descriptor
229
230 def birthday(self):
231 self.age += 1
232
233An interactive session shows that the :class:`Person` class has called
234:meth:`__set_name__` so that the field names would be recorded. Here
235we call :func:`vars` to lookup the descriptor without triggering it::
236
237 >>> vars(vars(Person)['name'])
238 {'public_name': 'name', 'private_name': '_name'}
239 >>> vars(vars(Person)['age'])
240 {'public_name': 'age', 'private_name': '_age'}
241
242The new class now logs access to both *name* and *age*::
243
244 >>> pete = Person('Peter P', 10)
245 INFO:root:Updating 'name' to 'Peter P'
246 INFO:root:Updating 'age' to 10
247 >>> kate = Person('Catherine C', 20)
248 INFO:root:Updating 'name' to 'Catherine C'
249 INFO:root:Updating 'age' to 20
250
251The two *Person* instances contain only the private names::
252
253 >>> vars(pete)
254 {'_name': 'Peter P', '_age': 10}
255 >>> vars(kate)
256 {'_name': 'Catherine C', '_age': 20}
257
258
259Closing thoughts
260----------------
261
262A :term:`descriptor` is what we call any object that defines :meth:`__get__`,
263:meth:`__set__`, or :meth:`__delete__`.
264
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700265Optionally, descriptors can have a :meth:`__set_name__` method. This is only
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700266used in cases where a descriptor needs to know either the class where it was
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700267created or the name of class variable it was assigned to.
268
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700269Descriptors get invoked by the dot operator during attribute lookup. If a
270descriptor is accessed indirectly with ``vars(some_class)[descriptor_name]``,
271the descriptor instance is returned without invoking it.
272
273Descriptors only work when used as class variables. When put in instances,
274they have no effect.
275
276The main motivation for descriptors is to provide a hook allowing objects
277stored in class variables to control what happens during dotted lookup.
278
279Traditionally, the calling class controls what happens during lookup.
280Descriptors invert that relationship and allow the data being looked-up to
281have a say in the matter.
282
283Descriptors are used throughout the language. It is how functions turn into
284bound methods. Common tools like :func:`classmethod`, :func:`staticmethod`,
285:func:`property`, and :func:`functools.cached_property` are all implemented as
286descriptors.
287
288
289Complete Practical Example
290^^^^^^^^^^^^^^^^^^^^^^^^^^
291
292In this example, we create a practical and powerful tool for locating
293notoriously hard to find data corruption bugs.
294
295
296Validator class
297---------------
298
299A validator is a descriptor for managed attribute access. Prior to storing
300any data, it verifies that the new value meets various type and range
301restrictions. If those restrictions aren't met, it raises an exception to
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700302prevent data corruption at its source.
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700303
304This :class:`Validator` class is both an :term:`abstract base class` and a
305managed attribute descriptor::
306
307 from abc import ABC, abstractmethod
308
309 class Validator(ABC):
310
311 def __set_name__(self, owner, name):
312 self.private_name = f'_{name}'
313
314 def __get__(self, obj, objtype=None):
315 return getattr(obj, self.private_name)
316
317 def __set__(self, obj, value):
318 self.validate(value)
319 setattr(obj, self.private_name, value)
320
321 @abstractmethod
322 def validate(self, value):
323 pass
324
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700325Custom validators need to inherit from :class:`Validator` and must supply a
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700326:meth:`validate` method to test various restrictions as needed.
327
328
329Custom validators
330-----------------
331
332Here are three practical data validation utilities:
333
3341) :class:`OneOf` verifies that a value is one of a restricted set of options.
335
3362) :class:`Number` verifies that a value is either an :class:`int` or
337 :class:`float`. Optionally, it verifies that a value is between a given
338 minimum or maximum.
339
3403) :class:`String` verifies that a value is a :class:`str`. Optionally, it
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700341 validates a given minimum or maximum length. It can validate a
342 user-defined `predicate
343 <https://en.wikipedia.org/wiki/Predicate_(mathematical_logic)>`_ as well.
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700344
345::
346
347 class OneOf(Validator):
348
349 def __init__(self, *options):
350 self.options = set(options)
351
352 def validate(self, value):
353 if value not in self.options:
354 raise ValueError(f'Expected {value!r} to be one of {self.options!r}')
355
356 class Number(Validator):
357
358 def __init__(self, minvalue=None, maxvalue=None):
359 self.minvalue = minvalue
360 self.maxvalue = maxvalue
361
362 def validate(self, value):
363 if not isinstance(value, (int, float)):
364 raise TypeError(f'Expected {value!r} to be an int or float')
365 if self.minvalue is not None and value < self.minvalue:
366 raise ValueError(
367 f'Expected {value!r} to be at least {self.minvalue!r}'
368 )
369 if self.maxvalue is not None and value > self.maxvalue:
370 raise ValueError(
371 f'Expected {value!r} to be no more than {self.maxvalue!r}'
372 )
373
374 class String(Validator):
375
376 def __init__(self, minsize=None, maxsize=None, predicate=None):
377 self.minsize = minsize
378 self.maxsize = maxsize
379 self.predicate = predicate
380
381 def validate(self, value):
382 if not isinstance(value, str):
383 raise TypeError(f'Expected {value!r} to be an str')
384 if self.minsize is not None and len(value) < self.minsize:
385 raise ValueError(
386 f'Expected {value!r} to be no smaller than {self.minsize!r}'
387 )
388 if self.maxsize is not None and len(value) > self.maxsize:
389 raise ValueError(
390 f'Expected {value!r} to be no bigger than {self.maxsize!r}'
391 )
392 if self.predicate is not None and not self.predicate(value):
393 raise ValueError(
394 f'Expected {self.predicate} to be true for {value!r}'
395 )
396
397
398Practical use
399-------------
400
401Here's how the data validators can be used in a real class::
402
403 class Component:
404
405 name = String(minsize=3, maxsize=10, predicate=str.isupper)
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700406 kind = OneOf('wood', 'metal', 'plastic')
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700407 quantity = Number(minvalue=0)
408
409 def __init__(self, name, kind, quantity):
410 self.name = name
411 self.kind = kind
412 self.quantity = quantity
413
414The descriptors prevent invalid instances from being created::
415
416 Component('WIDGET', 'metal', 5) # Allowed.
417 Component('Widget', 'metal', 5) # Blocked: 'Widget' is not all uppercase
418 Component('WIDGET', 'metle', 5) # Blocked: 'metle' is misspelled
419 Component('WIDGET', 'metal', -5) # Blocked: -5 is negative
420 Component('WIDGET', 'metal', 'V') # Blocked: 'V' isn't a number
421
422
423Technical Tutorial
424^^^^^^^^^^^^^^^^^^
425
426What follows is a more technical tutorial for the mechanics and details of how
427descriptors work.
428
429
Georg Brandl45cceeb2010-05-19 21:39:51 +0000430Abstract
431--------
432
433Defines descriptors, summarizes the protocol, and shows how descriptors are
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700434called. Provides an example showing how object relational mappings work.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000435
436Learning about descriptors not only provides access to a larger toolset, it
437creates a deeper understanding of how Python works and an appreciation for the
438elegance of its design.
439
440
441Definition and Introduction
442---------------------------
443
444In general, a descriptor is an object attribute with "binding behavior", one
445whose attribute access has been overridden by methods in the descriptor
446protocol. Those methods are :meth:`__get__`, :meth:`__set__`, and
447:meth:`__delete__`. If any of those methods are defined for an object, it is
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700448said to be a :term:`descriptor`.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000449
450The default behavior for attribute access is to get, set, or delete the
451attribute from an object's dictionary. For instance, ``a.x`` has a lookup chain
452starting with ``a.__dict__['x']``, then ``type(a).__dict__['x']``, and
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700453continuing through the base classes of ``type(a)``. If the
Georg Brandl45cceeb2010-05-19 21:39:51 +0000454looked-up value is an object defining one of the descriptor methods, then Python
455may override the default behavior and invoke the descriptor method instead.
456Where this occurs in the precedence chain depends on which descriptor methods
Florent Xiclunaaa6c1d22011-12-12 18:54:29 +0100457were defined.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000458
459Descriptors are a powerful, general purpose protocol. They are the mechanism
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700460behind properties, methods, static methods, class methods, and
461:func:`super()`. They are used throughout Python itself. Descriptors
462simplify the underlying C code and offer a flexible set of new tools for
463everyday Python programs.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000464
465
466Descriptor Protocol
467-------------------
468
NotAFile28ea4c22018-09-10 23:35:38 +0200469``descr.__get__(self, obj, type=None) -> value``
Georg Brandl45cceeb2010-05-19 21:39:51 +0000470
NotAFile28ea4c22018-09-10 23:35:38 +0200471``descr.__set__(self, obj, value) -> None``
Georg Brandl45cceeb2010-05-19 21:39:51 +0000472
NotAFile28ea4c22018-09-10 23:35:38 +0200473``descr.__delete__(self, obj) -> None``
Georg Brandl45cceeb2010-05-19 21:39:51 +0000474
475That is all there is to it. Define any of these methods and an object is
476considered a descriptor and can override default behavior upon being looked up
477as an attribute.
478
Aaron Hall, MBA4054b172018-05-20 19:46:42 -0400479If an object defines :meth:`__set__` or :meth:`__delete__`, it is considered
Georg Brandl45cceeb2010-05-19 21:39:51 +0000480a data descriptor. Descriptors that only define :meth:`__get__` are called
481non-data descriptors (they are typically used for methods but other uses are
482possible).
483
484Data and non-data descriptors differ in how overrides are calculated with
485respect to entries in an instance's dictionary. If an instance's dictionary
486has an entry with the same name as a data descriptor, the data descriptor
487takes precedence. If an instance's dictionary has an entry with the same
488name as a non-data descriptor, the dictionary entry takes precedence.
489
490To make a read-only data descriptor, define both :meth:`__get__` and
491:meth:`__set__` with the :meth:`__set__` raising an :exc:`AttributeError` when
492called. Defining the :meth:`__set__` method with an exception raising
493placeholder is enough to make it a data descriptor.
494
495
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800496Overview of Descriptor Invocation
497---------------------------------
Georg Brandl45cceeb2010-05-19 21:39:51 +0000498
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800499A descriptor can be called directly with ``desc.__get__(obj)`` or
500``desc.__get__(None, cls)``.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000501
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700502But it is more common for a descriptor to be invoked automatically from
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800503attribute access.
504
505The expression ``obj.x`` looks up the attribute ``x`` in the chain of
506namespaces for ``obj``. If the search finds a descriptor, its :meth:`__get__`
507method is invoked according to the precedence rules listed below.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000508
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700509The details of invocation depend on whether ``obj`` is an object, class, or
510instance of super.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000511
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700512
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800513Invocation from an Instance
514---------------------------
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700515
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800516Instance lookup scans through a chain of namespaces giving data descriptors
517the highest priority, followed by instance variables, then non-data
518descriptors, then class variables, and lastly :meth:`__getattr__` if it is
519provided.
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700520
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800521If a descriptor is found for ``a.x``, then it is invoked with:
522``desc.__get__(a, type(a))``.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000523
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800524The logic for a dotted lookup is in :meth:`object.__getattribute__`. Here is
525a pure Python equivalent::
Georg Brandl45cceeb2010-05-19 21:39:51 +0000526
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800527 def object_getattribute(obj, name):
528 "Emulate PyObject_GenericGetAttr() in Objects/object.c"
529 null = object()
530 objtype = type(obj)
531 value = getattr(objtype, name, null)
532 if value is not null and hasattr(value, '__get__'):
533 if hasattr(value, '__set__') or hasattr(value, '__delete__'):
534 return value.__get__(obj, objtype) # data descriptor
535 try:
536 return vars(obj)[name] # instance variable
537 except (KeyError, TypeError):
538 pass
539 if hasattr(value, '__get__'):
540 return value.__get__(obj, objtype) # non-data descriptor
541 if value is not null:
542 return value # class variable
543 # Emulate slot_tp_getattr_hook() in Objects/typeobject.c
544 if hasattr(objtype, '__getattr__'):
545 return objtype.__getattr__(obj, name) # __getattr__ hook
546 raise AttributeError(name)
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700547
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800548The :exc:`TypeError` exception handler is needed because the instance dictionary
549doesn't exist when its class defines :term:`__slots__`.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000550
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800551
552Invocation from a Class
553-----------------------
554
555The logic for a dotted lookup such as ``A.x`` is in
556:meth:`type.__getattribute__`. The steps are similar to those for
557:meth:`object.__getattribute__` but the instance dictionary lookup is replaced
558by a search through the class's :term:`method resolution order`.
559
560If a descriptor is found, it is invoked with ``desc.__get__(None, A)``.
561
562The full C implementation can be found in :c:func:`type_getattro()` and
563:c:func:`_PyType_Lookup()` in :source:`Objects/typeobject.c`.
564
565
566Invocation from Super
567---------------------
568
569The logic for super's dotted lookup is in the :meth:`__getattribute__` method for
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700570object returned by :class:`super()`.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000571
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800572A dotted lookup such as ``super(A, obj).m`` searches ``obj.__class__.__mro__``
573for the base class ``B`` immediately following ``A`` and then returns
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700574``B.__dict__['m'].__get__(obj, A)``. If not a descriptor, ``m`` is returned
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800575unchanged.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000576
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800577The full C implementation can be found in :c:func:`super_getattro()` in
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700578:source:`Objects/typeobject.c`. A pure Python equivalent can be found in
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800579`Guido's Tutorial
580<https://www.python.org/download/releases/2.2.3/descrintro/#cooperation>`_.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000581
Georg Brandl45cceeb2010-05-19 21:39:51 +0000582
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800583Summary of Invocation Logic
584---------------------------
585
586The mechanism for descriptors is embedded in the :meth:`__getattribute__()`
587methods for :class:`object`, :class:`type`, and :func:`super`.
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700588
589The important points to remember are:
590
591* Descriptors are invoked by the :meth:`__getattribute__` method.
592
593* Classes inherit this machinery from :class:`object`, :class:`type`, or
594 :func:`super`.
595
596* Overriding :meth:`__getattribute__` prevents automatic descriptor calls
597 because all the descriptor logic is in that method.
598
599* :meth:`object.__getattribute__` and :meth:`type.__getattribute__` make
600 different calls to :meth:`__get__`. The first includes the instance and may
601 include the class. The second puts in ``None`` for the instance and always
602 includes the class.
603
604* Data descriptors always override instance dictionaries.
605
606* Non-data descriptors may be overridden by instance dictionaries.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000607
608
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700609Automatic Name Notification
610---------------------------
611
612Sometimes it is desirable for a descriptor to know what class variable name it
613was assigned to. When a new class is created, the :class:`type` metaclass
614scans the dictionary of the new class. If any of the entries are descriptors
615and if they define :meth:`__set_name__`, that method is called with two
616arguments. The *owner* is the class where the descriptor is used, the *name*
617is class variable the descriptor was assigned to.
618
619The implementation details are in :c:func:`type_new()` and
620:c:func:`set_names()` in :source:`Objects/typeobject.c`.
621
622Since the update logic is in :meth:`type.__new__`, notifications only take
623place at the time of class creation. If descriptors are added to the class
624afterwards, :meth:`__set_name__` will need to be called manually.
625
626
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700627ORM Example
628-----------
Georg Brandl45cceeb2010-05-19 21:39:51 +0000629
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700630The following code is simplified skeleton showing how data descriptors could
631be used to implement an `object relational mapping
632<https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping>`_.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000633
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700634The essential idea is that the data is stored in an external database. The
635Python instances only hold keys to the database's tables. Descriptors take
636care of lookups or updates::
Georg Brandl45cceeb2010-05-19 21:39:51 +0000637
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700638 class Field:
639
640 def __set_name__(self, owner, name):
641 self.fetch = f'SELECT {name} FROM {owner.table} WHERE {owner.key}=?;'
642 self.store = f'UPDATE {owner.table} SET {name}=? WHERE {owner.key}=?;'
Georg Brandl45cceeb2010-05-19 21:39:51 +0000643
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700644 def __get__(self, obj, objtype=None):
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700645 return conn.execute(self.fetch, [obj.key]).fetchone()[0]
Georg Brandl45cceeb2010-05-19 21:39:51 +0000646
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700647 def __set__(self, obj, value):
648 conn.execute(self.store, [value, obj.key])
649 conn.commit()
Georg Brandl45cceeb2010-05-19 21:39:51 +0000650
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700651We can use the :class:`Field` class to define "models" that describe the schema
652for each table in a database::
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700653
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700654 class Movie:
655 table = 'Movies' # Table name
656 key = 'title' # Primary key
657 director = Field()
658 year = Field()
Georg Brandl45cceeb2010-05-19 21:39:51 +0000659
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700660 def __init__(self, key):
661 self.key = key
662
663 class Song:
664 table = 'Music'
665 key = 'title'
666 artist = Field()
667 year = Field()
668 genre = Field()
669
670 def __init__(self, key):
671 self.key = key
672
673An interactive session shows how data is retrieved from the database and how
674it can be updated::
675
676 >>> import sqlite3
677 >>> conn = sqlite3.connect('entertainment.db')
678
679 >>> Movie('Star Wars').director
680 'George Lucas'
681 >>> jaws = Movie('Jaws')
682 >>> f'Released in {jaws.year} by {jaws.director}'
683 'Released in 1975 by Steven Spielberg'
684
685 >>> Song('Country Roads').artist
686 'John Denver'
687
688 >>> Movie('Star Wars').director = 'J.J. Abrams'
689 >>> Movie('Star Wars').director
690 'J.J. Abrams'
691
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700692Pure Python Equivalents
693^^^^^^^^^^^^^^^^^^^^^^^
694
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700695The descriptor protocol is simple and offers exciting possibilities. Several
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800696use cases are so common that they have been prepackaged into built-in tools.
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700697Properties, bound methods, static methods, and class methods are all based on
698the descriptor protocol.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000699
700
701Properties
702----------
703
704Calling :func:`property` is a succinct way of building a data descriptor that
705triggers function calls upon access to an attribute. Its signature is::
706
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700707 property(fget=None, fset=None, fdel=None, doc=None) -> property
Georg Brandl45cceeb2010-05-19 21:39:51 +0000708
709The documentation shows a typical use to define a managed attribute ``x``::
710
Serhiy Storchakae042a452019-06-10 13:35:52 +0300711 class C:
Georg Brandl45cceeb2010-05-19 21:39:51 +0000712 def getx(self): return self.__x
713 def setx(self, value): self.__x = value
714 def delx(self): del self.__x
715 x = property(getx, setx, delx, "I'm the 'x' property.")
716
717To see how :func:`property` is implemented in terms of the descriptor protocol,
718here is a pure Python equivalent::
719
Serhiy Storchakae042a452019-06-10 13:35:52 +0300720 class Property:
Georg Brandl45cceeb2010-05-19 21:39:51 +0000721 "Emulate PyProperty_Type() in Objects/descrobject.c"
722
723 def __init__(self, fget=None, fset=None, fdel=None, doc=None):
724 self.fget = fget
725 self.fset = fset
726 self.fdel = fdel
Raymond Hettinger632c8c82013-03-10 09:41:18 -0700727 if doc is None and fget is not None:
728 doc = fget.__doc__
Georg Brandl45cceeb2010-05-19 21:39:51 +0000729 self.__doc__ = doc
730
731 def __get__(self, obj, objtype=None):
732 if obj is None:
733 return self
734 if self.fget is None:
Raymond Hettinger632c8c82013-03-10 09:41:18 -0700735 raise AttributeError("unreadable attribute")
Georg Brandl45cceeb2010-05-19 21:39:51 +0000736 return self.fget(obj)
737
738 def __set__(self, obj, value):
739 if self.fset is None:
Raymond Hettinger632c8c82013-03-10 09:41:18 -0700740 raise AttributeError("can't set attribute")
Georg Brandl45cceeb2010-05-19 21:39:51 +0000741 self.fset(obj, value)
742
743 def __delete__(self, obj):
744 if self.fdel is None:
Raymond Hettinger632c8c82013-03-10 09:41:18 -0700745 raise AttributeError("can't delete attribute")
Georg Brandl45cceeb2010-05-19 21:39:51 +0000746 self.fdel(obj)
747
Raymond Hettinger632c8c82013-03-10 09:41:18 -0700748 def getter(self, fget):
749 return type(self)(fget, self.fset, self.fdel, self.__doc__)
750
751 def setter(self, fset):
752 return type(self)(self.fget, fset, self.fdel, self.__doc__)
753
754 def deleter(self, fdel):
755 return type(self)(self.fget, self.fset, fdel, self.__doc__)
756
Georg Brandl45cceeb2010-05-19 21:39:51 +0000757The :func:`property` builtin helps whenever a user interface has granted
758attribute access and then subsequent changes require the intervention of a
759method.
760
761For instance, a spreadsheet class may grant access to a cell value through
762``Cell('b10').value``. Subsequent improvements to the program require the cell
763to be recalculated on every access; however, the programmer does not want to
764affect existing client code accessing the attribute directly. The solution is
765to wrap access to the value attribute in a property data descriptor::
766
Serhiy Storchakae042a452019-06-10 13:35:52 +0300767 class Cell:
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700768 ...
769
770 @property
771 def value(self):
_ = NaNb066edf2017-06-23 11:54:35 +0800772 "Recalculate the cell before returning value"
Georg Brandl45cceeb2010-05-19 21:39:51 +0000773 self.recalc()
_ = NaNb066edf2017-06-23 11:54:35 +0800774 return self._value
Georg Brandl45cceeb2010-05-19 21:39:51 +0000775
776
777Functions and Methods
778---------------------
779
780Python's object oriented features are built upon a function based environment.
781Using non-data descriptors, the two are merged seamlessly.
782
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700783Functions stored in class dictionaries get turned into methods when invoked.
784Methods only differ from regular functions in that the object instance is
785prepended to the other arguments. By convention, the instance is called
786*self* but could be called *this* or any other variable name.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000787
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700788Methods can be created manually with :class:`types.MethodType` which is
789roughly equivalent to::
790
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700791 class MethodType:
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700792 "Emulate Py_MethodType in Objects/classobject.c"
793
794 def __init__(self, func, obj):
795 self.__func__ = func
796 self.__self__ = obj
797
798 def __call__(self, *args, **kwargs):
799 func = self.__func__
800 obj = self.__self__
801 return func(obj, *args, **kwargs)
802
803To support automatic creation of methods, functions include the
804:meth:`__get__` method for binding methods during attribute access. This
805means that functions are non-data descriptors which return bound methods
806during dotted lookup from an instance. Here's how it works::
Georg Brandl45cceeb2010-05-19 21:39:51 +0000807
Serhiy Storchakae042a452019-06-10 13:35:52 +0300808 class Function:
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700809 ...
810
Georg Brandl45cceeb2010-05-19 21:39:51 +0000811 def __get__(self, obj, objtype=None):
812 "Simulate func_descr_get() in Objects/funcobject.c"
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700813 if obj is None:
814 return self
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700815 return MethodType(self, obj)
Georg Brandl45cceeb2010-05-19 21:39:51 +0000816
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700817Running the following class in the interpreter shows how the function
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700818descriptor works in practice::
Georg Brandl45cceeb2010-05-19 21:39:51 +0000819
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700820 class D:
821 def f(self, x):
822 return x
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700823
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700824The function has a :term:`qualified name` attribute to support introspection::
825
826 >>> D.f.__qualname__
827 'D.f'
828
829Accessing the function through the class dictionary does not invoke
830:meth:`__get__`. Instead, it just returns the underlying function object::
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700831
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700832 >>> D.__dict__['f']
833 <function D.f at 0x00C45070>
834
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700835Dotted access from a class calls :meth:`__get__` which just returns the
836underlying function unchanged::
837
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700838 >>> D.f
839 <function D.f at 0x00C45070>
840
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700841The interesting behavior occurs during dotted access from an instance. The
842dotted lookup calls :meth:`__get__` which returns a bound method object::
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700843
844 >>> d = D()
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700845 >>> d.f
Georg Brandl45cceeb2010-05-19 21:39:51 +0000846 <bound method D.f of <__main__.D object at 0x00B18C90>>
847
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700848Internally, the bound method stores the underlying function and the bound
849instance::
850
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700851 >>> d.f.__func__
852 <function D.f at 0x1012e5ae8>
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700853
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700854 >>> d.f.__self__
855 <__main__.D object at 0x1012e1f98>
Georg Brandl45cceeb2010-05-19 21:39:51 +0000856
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700857If you have ever wondered where *self* comes from in regular methods or where
858*cls* comes from in class methods, this is it!
859
Georg Brandl45cceeb2010-05-19 21:39:51 +0000860
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700861Static Methods
862--------------
Georg Brandl45cceeb2010-05-19 21:39:51 +0000863
864Non-data descriptors provide a simple mechanism for variations on the usual
865patterns of binding functions into methods.
866
867To recap, functions have a :meth:`__get__` method so that they can be converted
Serhiy Storchakad65c9492015-11-02 14:10:23 +0200868to a method when accessed as attributes. The non-data descriptor transforms an
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700869``obj.f(*args)`` call into ``f(obj, *args)``. Calling ``cls.f(*args)``
Georg Brandl45cceeb2010-05-19 21:39:51 +0000870becomes ``f(*args)``.
871
872This chart summarizes the binding and its two most useful variants:
873
874 +-----------------+----------------------+------------------+
875 | Transformation | Called from an | Called from a |
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700876 | | object | class |
Georg Brandl45cceeb2010-05-19 21:39:51 +0000877 +=================+======================+==================+
878 | function | f(obj, \*args) | f(\*args) |
879 +-----------------+----------------------+------------------+
880 | staticmethod | f(\*args) | f(\*args) |
881 +-----------------+----------------------+------------------+
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700882 | classmethod | f(type(obj), \*args) | f(cls, \*args) |
Georg Brandl45cceeb2010-05-19 21:39:51 +0000883 +-----------------+----------------------+------------------+
884
885Static methods return the underlying function without changes. Calling either
886``c.f`` or ``C.f`` is the equivalent of a direct lookup into
887``object.__getattribute__(c, "f")`` or ``object.__getattribute__(C, "f")``. As a
888result, the function becomes identically accessible from either an object or a
889class.
890
891Good candidates for static methods are methods that do not reference the
892``self`` variable.
893
894For instance, a statistics package may include a container class for
895experimental data. The class provides normal methods for computing the average,
896mean, median, and other descriptive statistics that depend on the data. However,
897there may be useful functions which are conceptually related but do not depend
898on the data. For instance, ``erf(x)`` is handy conversion routine that comes up
899in statistical work but does not directly depend on a particular dataset.
900It can be called either from an object or the class: ``s.erf(1.5) --> .9332`` or
901``Sample.erf(1.5) --> .9332``.
902
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700903Since static methods return the underlying function with no changes, the
904example calls are unexciting::
Georg Brandl45cceeb2010-05-19 21:39:51 +0000905
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700906 class E:
907 @staticmethod
908 def f(x):
909 print(x)
910
Shubham Aggarwalabbdd1f2019-03-20 08:25:55 +0530911 >>> E.f(3)
Georg Brandl45cceeb2010-05-19 21:39:51 +0000912 3
Shubham Aggarwalabbdd1f2019-03-20 08:25:55 +0530913 >>> E().f(3)
Georg Brandl45cceeb2010-05-19 21:39:51 +0000914 3
915
916Using the non-data descriptor protocol, a pure Python version of
917:func:`staticmethod` would look like this::
918
Serhiy Storchakae042a452019-06-10 13:35:52 +0300919 class StaticMethod:
Serhiy Storchakadba90392016-05-10 12:01:23 +0300920 "Emulate PyStaticMethod_Type() in Objects/funcobject.c"
Georg Brandl45cceeb2010-05-19 21:39:51 +0000921
Serhiy Storchakadba90392016-05-10 12:01:23 +0300922 def __init__(self, f):
923 self.f = f
Georg Brandl45cceeb2010-05-19 21:39:51 +0000924
Serhiy Storchakadba90392016-05-10 12:01:23 +0300925 def __get__(self, obj, objtype=None):
926 return self.f
Georg Brandl45cceeb2010-05-19 21:39:51 +0000927
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700928
929Class Methods
930-------------
931
Georg Brandl45cceeb2010-05-19 21:39:51 +0000932Unlike static methods, class methods prepend the class reference to the
933argument list before calling the function. This format is the same
934for whether the caller is an object or a class::
935
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700936 class F:
937 @classmethod
938 def f(cls, x):
939 return cls.__name__, x
940
941 >>> print(F.f(3))
942 ('F', 3)
943 >>> print(F().f(3))
944 ('F', 3)
Georg Brandl45cceeb2010-05-19 21:39:51 +0000945
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700946This behavior is useful whenever the method only needs to have a class
947reference and does rely on data stored in a specific instance. One use for
948class methods is to create alternate class constructors. For example, the
949classmethod :func:`dict.fromkeys` creates a new dictionary from a list of
950keys. The pure Python equivalent is::
Georg Brandl45cceeb2010-05-19 21:39:51 +0000951
Serhiy Storchakae042a452019-06-10 13:35:52 +0300952 class Dict:
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700953 ...
954
955 @classmethod
956 def fromkeys(cls, iterable, value=None):
Georg Brandl45cceeb2010-05-19 21:39:51 +0000957 "Emulate dict_fromkeys() in Objects/dictobject.c"
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700958 d = cls()
Georg Brandl45cceeb2010-05-19 21:39:51 +0000959 for key in iterable:
960 d[key] = value
961 return d
Georg Brandl45cceeb2010-05-19 21:39:51 +0000962
963Now a new dictionary of unique keys can be constructed like this::
964
965 >>> Dict.fromkeys('abracadabra')
966 {'a': None, 'r': None, 'b': None, 'c': None, 'd': None}
967
968Using the non-data descriptor protocol, a pure Python version of
969:func:`classmethod` would look like this::
970
Serhiy Storchakae042a452019-06-10 13:35:52 +0300971 class ClassMethod:
Serhiy Storchakadba90392016-05-10 12:01:23 +0300972 "Emulate PyClassMethod_Type() in Objects/funcobject.c"
Georg Brandl45cceeb2010-05-19 21:39:51 +0000973
Serhiy Storchakadba90392016-05-10 12:01:23 +0300974 def __init__(self, f):
975 self.f = f
Georg Brandl45cceeb2010-05-19 21:39:51 +0000976
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700977 def __get__(self, obj, cls=None):
978 if cls is None:
979 cls = type(obj)
Raymond Hettinger8e5b0fd2020-10-23 18:37:27 -0700980 if hasattr(obj, '__get__'):
981 return self.f.__get__(cls)
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700982 return MethodType(self.f, cls)
Raymond Hettinger8e5b0fd2020-10-23 18:37:27 -0700983
984The code path for ``hasattr(obj, '__get__')`` was added in Python 3.9 and
985makes it possible for :func:`classmethod` to support chained decorators.
986For example, a classmethod and property could be chained together::
987
988 class G:
989 @classmethod
990 @property
991 def __doc__(cls):
992 return f'A doc for {cls.__name__!r}'