blob: 76987fda22b59d5ca5300cab6aed933aa3795e7e [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,
Raymond Hettingerc272d402020-11-15 17:44:28 -080019 adding one feature at a time. Start here if you're new to descriptors.
Raymond Hettinger8d3d7312020-10-23 12:55:39 -070020
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
Raymond Hettingere9208f02020-11-01 20:15:50 -080030 into bound methods or about the implementation of common tools like
31 :func:`classmethod`, :func:`staticmethod`, :func:`property`, and
32 :term:`__slots__`.
Raymond Hettingere6a7ea42020-10-25 07:12:50 -070033
Raymond Hettinger8d3d7312020-10-23 12:55:39 -070034
35Primer
36^^^^^^
37
Raymond Hettinger4a9c6372020-10-24 20:34:39 -070038In this primer, we start with the most basic possible example and then we'll
39add new capabilities one by one.
Raymond Hettinger8d3d7312020-10-23 12:55:39 -070040
41
42Simple example: A descriptor that returns a constant
43----------------------------------------------------
44
Raymond Hettingerc272d402020-11-15 17:44:28 -080045The :class:`Ten` class is a descriptor that always returns the constant ``10``
46from its :meth:`__get__` method::
Raymond Hettinger8d3d7312020-10-23 12:55:39 -070047
48
49 class Ten:
50 def __get__(self, obj, objtype=None):
51 return 10
52
53To use the descriptor, it must be stored as a class variable in another class::
54
55 class A:
56 x = 5 # Regular class attribute
Raymond Hettinger148c76b2020-11-01 09:10:06 -080057 y = Ten() # Descriptor instance
Raymond Hettinger8d3d7312020-10-23 12:55:39 -070058
59An interactive session shows the difference between normal attribute lookup
60and descriptor lookup::
61
62 >>> a = A() # Make an instance of class A
63 >>> a.x # Normal attribute lookup
64 5
65 >>> a.y # Descriptor lookup
66 10
67
Raymond Hettingerc272d402020-11-15 17:44:28 -080068In the ``a.x`` attribute lookup, the dot operator finds the key ``x`` and the
69value ``5`` in the class dictionary. In the ``a.y`` lookup, the dot operator
70finds a descriptor instance, recognized by its ``__get__`` method, and calls
71that method which returns ``10``.
72
Raymond Hettinger8d3d7312020-10-23 12:55:39 -070073Note that the value ``10`` is not stored in either the class dictionary or the
74instance dictionary. Instead, the value ``10`` is computed on demand.
75
76This example shows how a simple descriptor works, but it isn't very useful.
77For retrieving constants, normal attribute lookup would be better.
78
79In the next section, we'll create something more useful, a dynamic lookup.
80
81
82Dynamic lookups
83---------------
84
Raymond Hettingerc272d402020-11-15 17:44:28 -080085Interesting descriptors typically run computations instead of returning
86constants::
Raymond Hettinger8d3d7312020-10-23 12:55:39 -070087
Raymond Hettinger8d3d7312020-10-23 12:55:39 -070088 import os
89
90 class DirectorySize:
91
92 def __get__(self, obj, objtype=None):
93 return len(os.listdir(obj.dirname))
94
95 class Directory:
96
Raymond Hettinger148c76b2020-11-01 09:10:06 -080097 size = DirectorySize() # Descriptor instance
Raymond Hettinger8d3d7312020-10-23 12:55:39 -070098
99 def __init__(self, dirname):
100 self.dirname = dirname # Regular instance attribute
101
102An interactive session shows that the lookup is dynamic — it computes
103different, updated answers each time::
104
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700105 >>> s = Directory('songs')
Raymond Hettingerc272d402020-11-15 17:44:28 -0800106 >>> g = Directory('games')
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700107 >>> s.size # The songs directory has twenty files
108 20
Raymond Hettingerc272d402020-11-15 17:44:28 -0800109 >>> g.size # The games directory has three files
110 3
111 >>> open('games/newfile').close() # Add a fourth file to the directory
112 >>> g.size # File count is automatically updated
113 4
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700114
115Besides showing how descriptors can run computations, this example also
116reveals the purpose of the parameters to :meth:`__get__`. The *self*
117parameter is *size*, an instance of *DirectorySize*. The *obj* parameter is
Raymond Hettinger80318772020-11-06 01:30:17 -0800118either *g* or *s*, an instance of *Directory*. It is the *obj* parameter that
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700119lets the :meth:`__get__` method learn the target directory. The *objtype*
120parameter is the class *Directory*.
121
122
123Managed attributes
124------------------
125
126A popular use for descriptors is managing access to instance data. The
127descriptor is assigned to a public attribute in the class dictionary while the
128actual data is stored as a private attribute in the instance dictionary. The
129descriptor's :meth:`__get__` and :meth:`__set__` methods are triggered when
130the public attribute is accessed.
131
132In the following example, *age* is the public attribute and *_age* is the
133private attribute. When the public attribute is accessed, the descriptor logs
134the lookup or update::
135
136 import logging
137
138 logging.basicConfig(level=logging.INFO)
139
140 class LoggedAgeAccess:
141
142 def __get__(self, obj, objtype=None):
143 value = obj._age
144 logging.info('Accessing %r giving %r', 'age', value)
145 return value
146
147 def __set__(self, obj, value):
148 logging.info('Updating %r to %r', 'age', value)
149 obj._age = value
150
151 class Person:
152
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800153 age = LoggedAgeAccess() # Descriptor instance
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700154
155 def __init__(self, name, age):
156 self.name = name # Regular instance attribute
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800157 self.age = age # Calls __set__()
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700158
159 def birthday(self):
160 self.age += 1 # Calls both __get__() and __set__()
161
162
163An interactive session shows that all access to the managed attribute *age* is
164logged, but that the regular attribute *name* is not logged::
165
166 >>> mary = Person('Mary M', 30) # The initial age update is logged
167 INFO:root:Updating 'age' to 30
168 >>> dave = Person('David D', 40)
169 INFO:root:Updating 'age' to 40
170
171 >>> vars(mary) # The actual data is in a private attribute
172 {'name': 'Mary M', '_age': 30}
173 >>> vars(dave)
174 {'name': 'David D', '_age': 40}
175
176 >>> mary.age # Access the data and log the lookup
177 INFO:root:Accessing 'age' giving 30
178 30
179 >>> mary.birthday() # Updates are logged as well
180 INFO:root:Accessing 'age' giving 30
181 INFO:root:Updating 'age' to 31
182
183 >>> dave.name # Regular attribute lookup isn't logged
184 'David D'
185 >>> dave.age # Only the managed attribute is logged
186 INFO:root:Accessing 'age' giving 40
187 40
188
Raymond Hettinger80318772020-11-06 01:30:17 -0800189One major issue with this example is that the private name *_age* is hardwired in
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700190the *LoggedAgeAccess* class. That means that each instance can only have one
191logged attribute and that its name is unchangeable. In the next example,
192we'll fix that problem.
193
194
Raymond Hettingere9208f02020-11-01 20:15:50 -0800195Customized names
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700196----------------
197
Raymond Hettinger80318772020-11-06 01:30:17 -0800198When a class uses descriptors, it can inform each descriptor about which
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700199variable name was used.
200
201In this example, the :class:`Person` class has two descriptor instances,
202*name* and *age*. When the :class:`Person` class is defined, it makes a
203callback to :meth:`__set_name__` in *LoggedAccess* so that the field names can
204be recorded, giving each descriptor its own *public_name* and *private_name*::
205
206 import logging
207
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700208 logging.basicConfig(level=logging.INFO)
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700209
210 class LoggedAccess:
211
212 def __set_name__(self, owner, name):
213 self.public_name = name
Raymond Hettingerc272d402020-11-15 17:44:28 -0800214 self.private_name = '_' + name
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700215
216 def __get__(self, obj, objtype=None):
217 value = getattr(obj, self.private_name)
218 logging.info('Accessing %r giving %r', self.public_name, value)
219 return value
220
221 def __set__(self, obj, value):
222 logging.info('Updating %r to %r', self.public_name, value)
223 setattr(obj, self.private_name, value)
224
225 class Person:
226
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800227 name = LoggedAccess() # First descriptor instance
228 age = LoggedAccess() # Second descriptor instance
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700229
230 def __init__(self, name, age):
231 self.name = name # Calls the first descriptor
232 self.age = age # Calls the second descriptor
233
234 def birthday(self):
235 self.age += 1
236
237An interactive session shows that the :class:`Person` class has called
238:meth:`__set_name__` so that the field names would be recorded. Here
Raymond Hettinger80318772020-11-06 01:30:17 -0800239we call :func:`vars` to look up the descriptor without triggering it::
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700240
241 >>> vars(vars(Person)['name'])
242 {'public_name': 'name', 'private_name': '_name'}
243 >>> vars(vars(Person)['age'])
244 {'public_name': 'age', 'private_name': '_age'}
245
246The new class now logs access to both *name* and *age*::
247
248 >>> pete = Person('Peter P', 10)
249 INFO:root:Updating 'name' to 'Peter P'
250 INFO:root:Updating 'age' to 10
251 >>> kate = Person('Catherine C', 20)
252 INFO:root:Updating 'name' to 'Catherine C'
253 INFO:root:Updating 'age' to 20
254
255The two *Person* instances contain only the private names::
256
257 >>> vars(pete)
258 {'_name': 'Peter P', '_age': 10}
259 >>> vars(kate)
260 {'_name': 'Catherine C', '_age': 20}
261
262
263Closing thoughts
264----------------
265
266A :term:`descriptor` is what we call any object that defines :meth:`__get__`,
267:meth:`__set__`, or :meth:`__delete__`.
268
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700269Optionally, descriptors can have a :meth:`__set_name__` method. This is only
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700270used in cases where a descriptor needs to know either the class where it was
Raymond Hettingerc272d402020-11-15 17:44:28 -0800271created or the name of class variable it was assigned to. (This method, if
272present, is called even if the class is not a descriptor.)
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700273
Raymond Hettingerc272d402020-11-15 17:44:28 -0800274Descriptors get invoked by the dot "operator" during attribute lookup. If a
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700275descriptor is accessed indirectly with ``vars(some_class)[descriptor_name]``,
276the descriptor instance is returned without invoking it.
277
278Descriptors only work when used as class variables. When put in instances,
279they have no effect.
280
281The main motivation for descriptors is to provide a hook allowing objects
Raymond Hettingerc272d402020-11-15 17:44:28 -0800282stored in class variables to control what happens during attribute lookup.
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700283
284Traditionally, the calling class controls what happens during lookup.
285Descriptors invert that relationship and allow the data being looked-up to
286have a say in the matter.
287
288Descriptors are used throughout the language. It is how functions turn into
289bound methods. Common tools like :func:`classmethod`, :func:`staticmethod`,
290:func:`property`, and :func:`functools.cached_property` are all implemented as
291descriptors.
292
293
294Complete Practical Example
295^^^^^^^^^^^^^^^^^^^^^^^^^^
296
297In this example, we create a practical and powerful tool for locating
298notoriously hard to find data corruption bugs.
299
300
301Validator class
302---------------
303
304A validator is a descriptor for managed attribute access. Prior to storing
305any data, it verifies that the new value meets various type and range
306restrictions. If those restrictions aren't met, it raises an exception to
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700307prevent data corruption at its source.
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700308
309This :class:`Validator` class is both an :term:`abstract base class` and a
310managed attribute descriptor::
311
312 from abc import ABC, abstractmethod
313
314 class Validator(ABC):
315
316 def __set_name__(self, owner, name):
Raymond Hettingerc272d402020-11-15 17:44:28 -0800317 self.private_name = '_' + name
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700318
319 def __get__(self, obj, objtype=None):
320 return getattr(obj, self.private_name)
321
322 def __set__(self, obj, value):
323 self.validate(value)
324 setattr(obj, self.private_name, value)
325
326 @abstractmethod
327 def validate(self, value):
328 pass
329
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700330Custom validators need to inherit from :class:`Validator` and must supply a
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700331:meth:`validate` method to test various restrictions as needed.
332
333
334Custom validators
335-----------------
336
337Here are three practical data validation utilities:
338
3391) :class:`OneOf` verifies that a value is one of a restricted set of options.
340
3412) :class:`Number` verifies that a value is either an :class:`int` or
342 :class:`float`. Optionally, it verifies that a value is between a given
343 minimum or maximum.
344
3453) :class:`String` verifies that a value is a :class:`str`. Optionally, it
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700346 validates a given minimum or maximum length. It can validate a
347 user-defined `predicate
348 <https://en.wikipedia.org/wiki/Predicate_(mathematical_logic)>`_ as well.
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700349
350::
351
352 class OneOf(Validator):
353
354 def __init__(self, *options):
355 self.options = set(options)
356
357 def validate(self, value):
358 if value not in self.options:
359 raise ValueError(f'Expected {value!r} to be one of {self.options!r}')
360
361 class Number(Validator):
362
363 def __init__(self, minvalue=None, maxvalue=None):
364 self.minvalue = minvalue
365 self.maxvalue = maxvalue
366
367 def validate(self, value):
368 if not isinstance(value, (int, float)):
369 raise TypeError(f'Expected {value!r} to be an int or float')
370 if self.minvalue is not None and value < self.minvalue:
371 raise ValueError(
372 f'Expected {value!r} to be at least {self.minvalue!r}'
373 )
374 if self.maxvalue is not None and value > self.maxvalue:
375 raise ValueError(
376 f'Expected {value!r} to be no more than {self.maxvalue!r}'
377 )
378
379 class String(Validator):
380
381 def __init__(self, minsize=None, maxsize=None, predicate=None):
382 self.minsize = minsize
383 self.maxsize = maxsize
384 self.predicate = predicate
385
386 def validate(self, value):
387 if not isinstance(value, str):
388 raise TypeError(f'Expected {value!r} to be an str')
389 if self.minsize is not None and len(value) < self.minsize:
390 raise ValueError(
391 f'Expected {value!r} to be no smaller than {self.minsize!r}'
392 )
393 if self.maxsize is not None and len(value) > self.maxsize:
394 raise ValueError(
395 f'Expected {value!r} to be no bigger than {self.maxsize!r}'
396 )
397 if self.predicate is not None and not self.predicate(value):
398 raise ValueError(
399 f'Expected {self.predicate} to be true for {value!r}'
400 )
401
402
403Practical use
404-------------
405
406Here's how the data validators can be used in a real class::
407
408 class Component:
409
410 name = String(minsize=3, maxsize=10, predicate=str.isupper)
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700411 kind = OneOf('wood', 'metal', 'plastic')
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700412 quantity = Number(minvalue=0)
413
414 def __init__(self, name, kind, quantity):
415 self.name = name
416 self.kind = kind
417 self.quantity = quantity
418
419The descriptors prevent invalid instances from being created::
420
421 Component('WIDGET', 'metal', 5) # Allowed.
422 Component('Widget', 'metal', 5) # Blocked: 'Widget' is not all uppercase
423 Component('WIDGET', 'metle', 5) # Blocked: 'metle' is misspelled
424 Component('WIDGET', 'metal', -5) # Blocked: -5 is negative
425 Component('WIDGET', 'metal', 'V') # Blocked: 'V' isn't a number
426
427
428Technical Tutorial
429^^^^^^^^^^^^^^^^^^
430
431What follows is a more technical tutorial for the mechanics and details of how
432descriptors work.
433
434
Georg Brandl45cceeb2010-05-19 21:39:51 +0000435Abstract
436--------
437
438Defines descriptors, summarizes the protocol, and shows how descriptors are
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700439called. Provides an example showing how object relational mappings work.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000440
441Learning about descriptors not only provides access to a larger toolset, it
Raymond Hettingerc272d402020-11-15 17:44:28 -0800442creates a deeper understanding of how Python works.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000443
444
Raymond Hettingere9208f02020-11-01 20:15:50 -0800445Definition and introduction
Georg Brandl45cceeb2010-05-19 21:39:51 +0000446---------------------------
447
Raymond Hettingerc272d402020-11-15 17:44:28 -0800448In general, a descriptor is an attribute value that has one of the methods in
449the descriptor protocol. Those methods are :meth:`__get__`, :meth:`__set__`,
450and :meth:`__delete__`. If any of those methods are defined for an the
451attribute, it is said to be a :term:`descriptor`.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000452
453The default behavior for attribute access is to get, set, or delete the
454attribute from an object's dictionary. For instance, ``a.x`` has a lookup chain
455starting with ``a.__dict__['x']``, then ``type(a).__dict__['x']``, and
Raymond Hettingerc272d402020-11-15 17:44:28 -0800456continuing through the method resolution order of ``type(a)``. If the
Georg Brandl45cceeb2010-05-19 21:39:51 +0000457looked-up value is an object defining one of the descriptor methods, then Python
458may override the default behavior and invoke the descriptor method instead.
459Where this occurs in the precedence chain depends on which descriptor methods
Florent Xiclunaaa6c1d22011-12-12 18:54:29 +0100460were defined.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000461
462Descriptors are a powerful, general purpose protocol. They are the mechanism
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700463behind properties, methods, static methods, class methods, and
464:func:`super()`. They are used throughout Python itself. Descriptors
465simplify the underlying C code and offer a flexible set of new tools for
466everyday Python programs.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000467
468
Raymond Hettingere9208f02020-11-01 20:15:50 -0800469Descriptor protocol
Georg Brandl45cceeb2010-05-19 21:39:51 +0000470-------------------
471
NotAFile28ea4c22018-09-10 23:35:38 +0200472``descr.__get__(self, obj, type=None) -> value``
Georg Brandl45cceeb2010-05-19 21:39:51 +0000473
NotAFile28ea4c22018-09-10 23:35:38 +0200474``descr.__set__(self, obj, value) -> None``
Georg Brandl45cceeb2010-05-19 21:39:51 +0000475
NotAFile28ea4c22018-09-10 23:35:38 +0200476``descr.__delete__(self, obj) -> None``
Georg Brandl45cceeb2010-05-19 21:39:51 +0000477
478That is all there is to it. Define any of these methods and an object is
479considered a descriptor and can override default behavior upon being looked up
480as an attribute.
481
Aaron Hall, MBA4054b172018-05-20 19:46:42 -0400482If an object defines :meth:`__set__` or :meth:`__delete__`, it is considered
Georg Brandl45cceeb2010-05-19 21:39:51 +0000483a data descriptor. Descriptors that only define :meth:`__get__` are called
Raymond Hettingerc272d402020-11-15 17:44:28 -0800484non-data descriptors (they are often used for methods but other uses are
Georg Brandl45cceeb2010-05-19 21:39:51 +0000485possible).
486
487Data and non-data descriptors differ in how overrides are calculated with
488respect to entries in an instance's dictionary. If an instance's dictionary
489has an entry with the same name as a data descriptor, the data descriptor
490takes precedence. If an instance's dictionary has an entry with the same
491name as a non-data descriptor, the dictionary entry takes precedence.
492
493To make a read-only data descriptor, define both :meth:`__get__` and
494:meth:`__set__` with the :meth:`__set__` raising an :exc:`AttributeError` when
495called. Defining the :meth:`__set__` method with an exception raising
496placeholder is enough to make it a data descriptor.
497
498
Raymond Hettingere9208f02020-11-01 20:15:50 -0800499Overview of descriptor invocation
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800500---------------------------------
Georg Brandl45cceeb2010-05-19 21:39:51 +0000501
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800502A descriptor can be called directly with ``desc.__get__(obj)`` or
503``desc.__get__(None, cls)``.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000504
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700505But it is more common for a descriptor to be invoked automatically from
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800506attribute access.
507
508The expression ``obj.x`` looks up the attribute ``x`` in the chain of
Raymond Hettingerc272d402020-11-15 17:44:28 -0800509namespaces for ``obj``. If the search finds a descriptor outside of the
510instance ``__dict__``, its :meth:`__get__` method is invoked according to the
511precedence rules listed below.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000512
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700513The details of invocation depend on whether ``obj`` is an object, class, or
514instance of super.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000515
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700516
Raymond Hettingere9208f02020-11-01 20:15:50 -0800517Invocation from an instance
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800518---------------------------
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700519
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800520Instance lookup scans through a chain of namespaces giving data descriptors
521the highest priority, followed by instance variables, then non-data
522descriptors, then class variables, and lastly :meth:`__getattr__` if it is
523provided.
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700524
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800525If a descriptor is found for ``a.x``, then it is invoked with:
526``desc.__get__(a, type(a))``.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000527
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800528The logic for a dotted lookup is in :meth:`object.__getattribute__`. Here is
529a pure Python equivalent::
Georg Brandl45cceeb2010-05-19 21:39:51 +0000530
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800531 def object_getattribute(obj, name):
532 "Emulate PyObject_GenericGetAttr() in Objects/object.c"
533 null = object()
534 objtype = type(obj)
Raymond Hettingerc272d402020-11-15 17:44:28 -0800535 cls_var = getattr(objtype, name, null)
536 descr_get = getattr(type(cls_var), '__get__', null)
537 if descr_get is not null:
538 if (hasattr(type(cls_var), '__set__')
539 or hasattr(type(cls_var), '__delete__')):
540 return descr_get(cls_var, obj, objtype) # data descriptor
541 if hasattr(obj, '__dict__') and name in vars(obj):
542 return vars(obj)[name] # instance variable
543 if descr_get is not null:
544 return descr_get(cls_var, obj, objtype) # non-data descriptor
545 if cls_var is not null:
546 return cls_var # class variable
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800547 raise AttributeError(name)
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700548
Raymond Hettingerc272d402020-11-15 17:44:28 -0800549Interestingly, attribute lookup doesn't call :meth:`object.__getattribute__`
550directly. Instead, both the dot operator and the :func:`getattr` function
551perform attribute lookup by way of a helper function::
552
553 def getattr_hook(obj, name):
554 "Emulate slot_tp_getattr_hook() in Objects/typeobject.c"
555 try:
556 return obj.__getattribute__(name)
557 except AttributeError:
558 if not hasattr(type(obj), '__getattr__'):
559 raise
560 return type(obj).__getattr__(obj, name) # __getattr__
561
562So if :meth:`__getattr__` exists, it is called whenever :meth:`__getattribute__`
563raises :exc:`AttributeError` (either directly or in one of the descriptor calls).
564
565Also, if a user calls :meth:`object.__getattribute__` directly, the
566:meth:`__getattr__` hook is bypassed entirely.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000567
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800568
Raymond Hettingere9208f02020-11-01 20:15:50 -0800569Invocation from a class
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800570-----------------------
571
572The logic for a dotted lookup such as ``A.x`` is in
573:meth:`type.__getattribute__`. The steps are similar to those for
574:meth:`object.__getattribute__` but the instance dictionary lookup is replaced
575by a search through the class's :term:`method resolution order`.
576
577If a descriptor is found, it is invoked with ``desc.__get__(None, A)``.
578
579The full C implementation can be found in :c:func:`type_getattro()` and
580:c:func:`_PyType_Lookup()` in :source:`Objects/typeobject.c`.
581
582
Raymond Hettingere9208f02020-11-01 20:15:50 -0800583Invocation from super
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800584---------------------
585
586The logic for super's dotted lookup is in the :meth:`__getattribute__` method for
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700587object returned by :class:`super()`.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000588
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800589A dotted lookup such as ``super(A, obj).m`` searches ``obj.__class__.__mro__``
590for the base class ``B`` immediately following ``A`` and then returns
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700591``B.__dict__['m'].__get__(obj, A)``. If not a descriptor, ``m`` is returned
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800592unchanged.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000593
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800594The full C implementation can be found in :c:func:`super_getattro()` in
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700595:source:`Objects/typeobject.c`. A pure Python equivalent can be found in
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800596`Guido's Tutorial
597<https://www.python.org/download/releases/2.2.3/descrintro/#cooperation>`_.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000598
Georg Brandl45cceeb2010-05-19 21:39:51 +0000599
Raymond Hettingere9208f02020-11-01 20:15:50 -0800600Summary of invocation logic
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800601---------------------------
602
603The mechanism for descriptors is embedded in the :meth:`__getattribute__()`
604methods for :class:`object`, :class:`type`, and :func:`super`.
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700605
606The important points to remember are:
607
608* Descriptors are invoked by the :meth:`__getattribute__` method.
609
610* Classes inherit this machinery from :class:`object`, :class:`type`, or
611 :func:`super`.
612
613* Overriding :meth:`__getattribute__` prevents automatic descriptor calls
614 because all the descriptor logic is in that method.
615
616* :meth:`object.__getattribute__` and :meth:`type.__getattribute__` make
617 different calls to :meth:`__get__`. The first includes the instance and may
618 include the class. The second puts in ``None`` for the instance and always
619 includes the class.
620
621* Data descriptors always override instance dictionaries.
622
623* Non-data descriptors may be overridden by instance dictionaries.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000624
625
Raymond Hettingere9208f02020-11-01 20:15:50 -0800626Automatic name notification
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700627---------------------------
628
629Sometimes it is desirable for a descriptor to know what class variable name it
630was assigned to. When a new class is created, the :class:`type` metaclass
631scans the dictionary of the new class. If any of the entries are descriptors
632and if they define :meth:`__set_name__`, that method is called with two
Raymond Hettinger80318772020-11-06 01:30:17 -0800633arguments. The *owner* is the class where the descriptor is used, and the
634*name* is the class variable the descriptor was assigned to.
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700635
636The implementation details are in :c:func:`type_new()` and
637:c:func:`set_names()` in :source:`Objects/typeobject.c`.
638
639Since the update logic is in :meth:`type.__new__`, notifications only take
640place at the time of class creation. If descriptors are added to the class
641afterwards, :meth:`__set_name__` will need to be called manually.
642
643
Raymond Hettingere9208f02020-11-01 20:15:50 -0800644ORM example
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700645-----------
Georg Brandl45cceeb2010-05-19 21:39:51 +0000646
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700647The following code is simplified skeleton showing how data descriptors could
648be used to implement an `object relational mapping
649<https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping>`_.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000650
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700651The essential idea is that the data is stored in an external database. The
652Python instances only hold keys to the database's tables. Descriptors take
653care of lookups or updates::
Georg Brandl45cceeb2010-05-19 21:39:51 +0000654
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700655 class Field:
656
657 def __set_name__(self, owner, name):
658 self.fetch = f'SELECT {name} FROM {owner.table} WHERE {owner.key}=?;'
659 self.store = f'UPDATE {owner.table} SET {name}=? WHERE {owner.key}=?;'
Georg Brandl45cceeb2010-05-19 21:39:51 +0000660
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700661 def __get__(self, obj, objtype=None):
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700662 return conn.execute(self.fetch, [obj.key]).fetchone()[0]
Georg Brandl45cceeb2010-05-19 21:39:51 +0000663
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700664 def __set__(self, obj, value):
665 conn.execute(self.store, [value, obj.key])
666 conn.commit()
Georg Brandl45cceeb2010-05-19 21:39:51 +0000667
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700668We can use the :class:`Field` class to define "models" that describe the schema
669for each table in a database::
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700670
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700671 class Movie:
672 table = 'Movies' # Table name
673 key = 'title' # Primary key
674 director = Field()
675 year = Field()
Georg Brandl45cceeb2010-05-19 21:39:51 +0000676
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700677 def __init__(self, key):
678 self.key = key
679
680 class Song:
681 table = 'Music'
682 key = 'title'
683 artist = Field()
684 year = Field()
685 genre = Field()
686
687 def __init__(self, key):
688 self.key = key
689
690An interactive session shows how data is retrieved from the database and how
691it can be updated::
692
693 >>> import sqlite3
694 >>> conn = sqlite3.connect('entertainment.db')
695
696 >>> Movie('Star Wars').director
697 'George Lucas'
698 >>> jaws = Movie('Jaws')
699 >>> f'Released in {jaws.year} by {jaws.director}'
700 'Released in 1975 by Steven Spielberg'
701
702 >>> Song('Country Roads').artist
703 'John Denver'
704
705 >>> Movie('Star Wars').director = 'J.J. Abrams'
706 >>> Movie('Star Wars').director
707 'J.J. Abrams'
708
Raymond Hettingerc272d402020-11-15 17:44:28 -0800709
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700710Pure Python Equivalents
711^^^^^^^^^^^^^^^^^^^^^^^
712
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700713The descriptor protocol is simple and offers exciting possibilities. Several
Raymond Hettinger148c76b2020-11-01 09:10:06 -0800714use cases are so common that they have been prepackaged into built-in tools.
Raymond Hettingere9208f02020-11-01 20:15:50 -0800715Properties, bound methods, static methods, class methods, and \_\_slots\_\_ are
716all based on the descriptor protocol.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000717
718
719Properties
720----------
721
722Calling :func:`property` is a succinct way of building a data descriptor that
Raymond Hettinger80318772020-11-06 01:30:17 -0800723triggers a function call upon access to an attribute. Its signature is::
Georg Brandl45cceeb2010-05-19 21:39:51 +0000724
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700725 property(fget=None, fset=None, fdel=None, doc=None) -> property
Georg Brandl45cceeb2010-05-19 21:39:51 +0000726
727The documentation shows a typical use to define a managed attribute ``x``::
728
Serhiy Storchakae042a452019-06-10 13:35:52 +0300729 class C:
Georg Brandl45cceeb2010-05-19 21:39:51 +0000730 def getx(self): return self.__x
731 def setx(self, value): self.__x = value
732 def delx(self): del self.__x
733 x = property(getx, setx, delx, "I'm the 'x' property.")
734
735To see how :func:`property` is implemented in terms of the descriptor protocol,
736here is a pure Python equivalent::
737
Serhiy Storchakae042a452019-06-10 13:35:52 +0300738 class Property:
Georg Brandl45cceeb2010-05-19 21:39:51 +0000739 "Emulate PyProperty_Type() in Objects/descrobject.c"
740
741 def __init__(self, fget=None, fset=None, fdel=None, doc=None):
742 self.fget = fget
743 self.fset = fset
744 self.fdel = fdel
Raymond Hettinger632c8c82013-03-10 09:41:18 -0700745 if doc is None and fget is not None:
746 doc = fget.__doc__
Georg Brandl45cceeb2010-05-19 21:39:51 +0000747 self.__doc__ = doc
748
749 def __get__(self, obj, objtype=None):
750 if obj is None:
751 return self
752 if self.fget is None:
Raymond Hettinger632c8c82013-03-10 09:41:18 -0700753 raise AttributeError("unreadable attribute")
Georg Brandl45cceeb2010-05-19 21:39:51 +0000754 return self.fget(obj)
755
756 def __set__(self, obj, value):
757 if self.fset is None:
Raymond Hettinger632c8c82013-03-10 09:41:18 -0700758 raise AttributeError("can't set attribute")
Georg Brandl45cceeb2010-05-19 21:39:51 +0000759 self.fset(obj, value)
760
761 def __delete__(self, obj):
762 if self.fdel is None:
Raymond Hettinger632c8c82013-03-10 09:41:18 -0700763 raise AttributeError("can't delete attribute")
Georg Brandl45cceeb2010-05-19 21:39:51 +0000764 self.fdel(obj)
765
Raymond Hettinger632c8c82013-03-10 09:41:18 -0700766 def getter(self, fget):
767 return type(self)(fget, self.fset, self.fdel, self.__doc__)
768
769 def setter(self, fset):
770 return type(self)(self.fget, fset, self.fdel, self.__doc__)
771
772 def deleter(self, fdel):
773 return type(self)(self.fget, self.fset, fdel, self.__doc__)
774
Georg Brandl45cceeb2010-05-19 21:39:51 +0000775The :func:`property` builtin helps whenever a user interface has granted
776attribute access and then subsequent changes require the intervention of a
777method.
778
779For instance, a spreadsheet class may grant access to a cell value through
780``Cell('b10').value``. Subsequent improvements to the program require the cell
781to be recalculated on every access; however, the programmer does not want to
782affect existing client code accessing the attribute directly. The solution is
783to wrap access to the value attribute in a property data descriptor::
784
Serhiy Storchakae042a452019-06-10 13:35:52 +0300785 class Cell:
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700786 ...
787
788 @property
789 def value(self):
_ = NaNb066edf2017-06-23 11:54:35 +0800790 "Recalculate the cell before returning value"
Georg Brandl45cceeb2010-05-19 21:39:51 +0000791 self.recalc()
_ = NaNb066edf2017-06-23 11:54:35 +0800792 return self._value
Georg Brandl45cceeb2010-05-19 21:39:51 +0000793
794
Raymond Hettingere9208f02020-11-01 20:15:50 -0800795Functions and methods
Georg Brandl45cceeb2010-05-19 21:39:51 +0000796---------------------
797
798Python's object oriented features are built upon a function based environment.
799Using non-data descriptors, the two are merged seamlessly.
800
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700801Functions stored in class dictionaries get turned into methods when invoked.
802Methods only differ from regular functions in that the object instance is
803prepended to the other arguments. By convention, the instance is called
804*self* but could be called *this* or any other variable name.
Georg Brandl45cceeb2010-05-19 21:39:51 +0000805
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700806Methods can be created manually with :class:`types.MethodType` which is
807roughly equivalent to::
808
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700809 class MethodType:
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700810 "Emulate Py_MethodType in Objects/classobject.c"
811
812 def __init__(self, func, obj):
813 self.__func__ = func
814 self.__self__ = obj
815
816 def __call__(self, *args, **kwargs):
817 func = self.__func__
818 obj = self.__self__
819 return func(obj, *args, **kwargs)
820
821To support automatic creation of methods, functions include the
822:meth:`__get__` method for binding methods during attribute access. This
Raymond Hettinger80318772020-11-06 01:30:17 -0800823means that functions are non-data descriptors that return bound methods
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700824during dotted lookup from an instance. Here's how it works::
Georg Brandl45cceeb2010-05-19 21:39:51 +0000825
Serhiy Storchakae042a452019-06-10 13:35:52 +0300826 class Function:
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700827 ...
828
Georg Brandl45cceeb2010-05-19 21:39:51 +0000829 def __get__(self, obj, objtype=None):
830 "Simulate func_descr_get() in Objects/funcobject.c"
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700831 if obj is None:
832 return self
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700833 return MethodType(self, obj)
Georg Brandl45cceeb2010-05-19 21:39:51 +0000834
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700835Running the following class in the interpreter shows how the function
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700836descriptor works in practice::
Georg Brandl45cceeb2010-05-19 21:39:51 +0000837
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700838 class D:
839 def f(self, x):
840 return x
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700841
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700842The function has a :term:`qualified name` attribute to support introspection::
843
844 >>> D.f.__qualname__
845 'D.f'
846
847Accessing the function through the class dictionary does not invoke
848:meth:`__get__`. Instead, it just returns the underlying function object::
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700849
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700850 >>> D.__dict__['f']
851 <function D.f at 0x00C45070>
852
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700853Dotted access from a class calls :meth:`__get__` which just returns the
854underlying function unchanged::
855
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700856 >>> D.f
857 <function D.f at 0x00C45070>
858
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700859The interesting behavior occurs during dotted access from an instance. The
860dotted lookup calls :meth:`__get__` which returns a bound method object::
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700861
862 >>> d = D()
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700863 >>> d.f
Georg Brandl45cceeb2010-05-19 21:39:51 +0000864 <bound method D.f of <__main__.D object at 0x00B18C90>>
865
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700866Internally, the bound method stores the underlying function and the bound
867instance::
868
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700869 >>> d.f.__func__
870 <function D.f at 0x1012e5ae8>
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700871
Raymond Hettinger0d4497b2017-09-25 01:05:49 -0700872 >>> d.f.__self__
873 <__main__.D object at 0x1012e1f98>
Georg Brandl45cceeb2010-05-19 21:39:51 +0000874
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700875If you have ever wondered where *self* comes from in regular methods or where
876*cls* comes from in class methods, this is it!
877
Georg Brandl45cceeb2010-05-19 21:39:51 +0000878
Raymond Hettingere9208f02020-11-01 20:15:50 -0800879Static methods
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700880--------------
Georg Brandl45cceeb2010-05-19 21:39:51 +0000881
882Non-data descriptors provide a simple mechanism for variations on the usual
883patterns of binding functions into methods.
884
885To recap, functions have a :meth:`__get__` method so that they can be converted
Serhiy Storchakad65c9492015-11-02 14:10:23 +0200886to a method when accessed as attributes. The non-data descriptor transforms an
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700887``obj.f(*args)`` call into ``f(obj, *args)``. Calling ``cls.f(*args)``
Georg Brandl45cceeb2010-05-19 21:39:51 +0000888becomes ``f(*args)``.
889
890This chart summarizes the binding and its two most useful variants:
891
892 +-----------------+----------------------+------------------+
893 | Transformation | Called from an | Called from a |
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700894 | | object | class |
Georg Brandl45cceeb2010-05-19 21:39:51 +0000895 +=================+======================+==================+
896 | function | f(obj, \*args) | f(\*args) |
897 +-----------------+----------------------+------------------+
898 | staticmethod | f(\*args) | f(\*args) |
899 +-----------------+----------------------+------------------+
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700900 | classmethod | f(type(obj), \*args) | f(cls, \*args) |
Georg Brandl45cceeb2010-05-19 21:39:51 +0000901 +-----------------+----------------------+------------------+
902
903Static methods return the underlying function without changes. Calling either
904``c.f`` or ``C.f`` is the equivalent of a direct lookup into
905``object.__getattribute__(c, "f")`` or ``object.__getattribute__(C, "f")``. As a
906result, the function becomes identically accessible from either an object or a
907class.
908
909Good candidates for static methods are methods that do not reference the
910``self`` variable.
911
912For instance, a statistics package may include a container class for
913experimental data. The class provides normal methods for computing the average,
914mean, median, and other descriptive statistics that depend on the data. However,
915there may be useful functions which are conceptually related but do not depend
916on the data. For instance, ``erf(x)`` is handy conversion routine that comes up
917in statistical work but does not directly depend on a particular dataset.
918It can be called either from an object or the class: ``s.erf(1.5) --> .9332`` or
919``Sample.erf(1.5) --> .9332``.
920
Raymond Hettinger4a9c6372020-10-24 20:34:39 -0700921Since static methods return the underlying function with no changes, the
922example calls are unexciting::
Georg Brandl45cceeb2010-05-19 21:39:51 +0000923
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700924 class E:
925 @staticmethod
926 def f(x):
927 print(x)
928
Shubham Aggarwalabbdd1f2019-03-20 08:25:55 +0530929 >>> E.f(3)
Georg Brandl45cceeb2010-05-19 21:39:51 +0000930 3
Shubham Aggarwalabbdd1f2019-03-20 08:25:55 +0530931 >>> E().f(3)
Georg Brandl45cceeb2010-05-19 21:39:51 +0000932 3
933
934Using the non-data descriptor protocol, a pure Python version of
935:func:`staticmethod` would look like this::
936
Serhiy Storchakae042a452019-06-10 13:35:52 +0300937 class StaticMethod:
Serhiy Storchakadba90392016-05-10 12:01:23 +0300938 "Emulate PyStaticMethod_Type() in Objects/funcobject.c"
Georg Brandl45cceeb2010-05-19 21:39:51 +0000939
Serhiy Storchakadba90392016-05-10 12:01:23 +0300940 def __init__(self, f):
941 self.f = f
Georg Brandl45cceeb2010-05-19 21:39:51 +0000942
Serhiy Storchakadba90392016-05-10 12:01:23 +0300943 def __get__(self, obj, objtype=None):
944 return self.f
Georg Brandl45cceeb2010-05-19 21:39:51 +0000945
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700946
Raymond Hettingere9208f02020-11-01 20:15:50 -0800947Class methods
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700948-------------
949
Georg Brandl45cceeb2010-05-19 21:39:51 +0000950Unlike static methods, class methods prepend the class reference to the
951argument list before calling the function. This format is the same
952for whether the caller is an object or a class::
953
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700954 class F:
955 @classmethod
956 def f(cls, x):
957 return cls.__name__, x
958
959 >>> print(F.f(3))
960 ('F', 3)
961 >>> print(F().f(3))
962 ('F', 3)
Georg Brandl45cceeb2010-05-19 21:39:51 +0000963
Raymond Hettingere6a7ea42020-10-25 07:12:50 -0700964This behavior is useful whenever the method only needs to have a class
965reference and does rely on data stored in a specific instance. One use for
966class methods is to create alternate class constructors. For example, the
967classmethod :func:`dict.fromkeys` creates a new dictionary from a list of
968keys. The pure Python equivalent is::
Georg Brandl45cceeb2010-05-19 21:39:51 +0000969
Serhiy Storchakae042a452019-06-10 13:35:52 +0300970 class Dict:
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700971 ...
972
973 @classmethod
974 def fromkeys(cls, iterable, value=None):
Georg Brandl45cceeb2010-05-19 21:39:51 +0000975 "Emulate dict_fromkeys() in Objects/dictobject.c"
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700976 d = cls()
Georg Brandl45cceeb2010-05-19 21:39:51 +0000977 for key in iterable:
978 d[key] = value
979 return d
Georg Brandl45cceeb2010-05-19 21:39:51 +0000980
981Now a new dictionary of unique keys can be constructed like this::
982
983 >>> Dict.fromkeys('abracadabra')
984 {'a': None, 'r': None, 'b': None, 'c': None, 'd': None}
985
986Using the non-data descriptor protocol, a pure Python version of
987:func:`classmethod` would look like this::
988
Serhiy Storchakae042a452019-06-10 13:35:52 +0300989 class ClassMethod:
Serhiy Storchakadba90392016-05-10 12:01:23 +0300990 "Emulate PyClassMethod_Type() in Objects/funcobject.c"
Georg Brandl45cceeb2010-05-19 21:39:51 +0000991
Serhiy Storchakadba90392016-05-10 12:01:23 +0300992 def __init__(self, f):
993 self.f = f
Georg Brandl45cceeb2010-05-19 21:39:51 +0000994
Raymond Hettinger8d3d7312020-10-23 12:55:39 -0700995 def __get__(self, obj, cls=None):
996 if cls is None:
997 cls = type(obj)
Raymond Hettinger8e5b0fd2020-10-23 18:37:27 -0700998 if hasattr(obj, '__get__'):
999 return self.f.__get__(cls)
Raymond Hettingere6a7ea42020-10-25 07:12:50 -07001000 return MethodType(self.f, cls)
Raymond Hettinger8e5b0fd2020-10-23 18:37:27 -07001001
1002The code path for ``hasattr(obj, '__get__')`` was added in Python 3.9 and
1003makes it possible for :func:`classmethod` to support chained decorators.
1004For example, a classmethod and property could be chained together::
1005
1006 class G:
1007 @classmethod
1008 @property
1009 def __doc__(cls):
1010 return f'A doc for {cls.__name__!r}'
Raymond Hettinger74fa4642020-11-01 18:02:37 -08001011
Raymond Hettingere9208f02020-11-01 20:15:50 -08001012Member objects and __slots__
1013----------------------------
Raymond Hettinger74fa4642020-11-01 18:02:37 -08001014
1015When a class defines ``__slots__``, it replaces instance dictionaries with a
1016fixed-length array of slot values. From a user point of view that has
1017several effects:
1018
10191. Provides immediate detection of bugs due to misspelled attribute
1020assignments. Only attribute names specified in ``__slots__`` are allowed::
1021
1022 class Vehicle:
1023 __slots__ = ('id_number', 'make', 'model')
1024
1025 >>> auto = Vehicle()
1026 >>> auto.id_nubmer = 'VYE483814LQEX'
1027 Traceback (most recent call last):
1028 ...
1029 AttributeError: 'Vehicle' object has no attribute 'id_nubmer'
1030
10312. Helps create immutable objects where descriptors manage access to private
1032attributes stored in ``__slots__``::
1033
1034 class Immutable:
1035
Raymond Hettinger80318772020-11-06 01:30:17 -08001036 __slots__ = ('_dept', '_name') # Replace the instance dictionary
Raymond Hettinger74fa4642020-11-01 18:02:37 -08001037
1038 def __init__(self, dept, name):
1039 self._dept = dept # Store to private attribute
1040 self._name = name # Store to private attribute
1041
1042 @property # Read-only descriptor
1043 def dept(self):
1044 return self._dept
1045
1046 @property
1047 def name(self): # Read-only descriptor
1048 return self._name
1049
1050 mark = Immutable('Botany', 'Mark Watney') # Create an immutable instance
1051
10523. Saves memory. On a 64-bit Linux build, an instance with two attributes
1053takes 48 bytes with ``__slots__`` and 152 bytes without. This `flyweight
1054design pattern <https://en.wikipedia.org/wiki/Flyweight_pattern>`_ likely only
1055matters when a large number of instances are going to be created.
1056
10574. Blocks tools like :func:`functools.cached_property` which require an
1058instance dictionary to function correctly::
1059
1060 from functools import cached_property
1061
1062 class CP:
1063 __slots__ = () # Eliminates the instance dict
1064
1065 @cached_property # Requires an instance dict
1066 def pi(self):
1067 return 4 * sum((-1.0)**n / (2.0*n + 1.0)
1068 for n in reversed(range(100_000)))
1069
1070 >>> CP().pi
1071 Traceback (most recent call last):
1072 ...
1073 TypeError: No '__dict__' attribute on 'CP' instance to cache 'pi' property.
1074
1075It's not possible to create an exact drop-in pure Python version of
1076``__slots__`` because it requires direct access to C structures and control
1077over object memory allocation. However, we can build a mostly faithful
1078simulation where the actual C structure for slots is emulated by a private
1079``_slotvalues`` list. Reads and writes to that private structure are managed
1080by member descriptors::
1081
1082 class Member:
1083
1084 def __init__(self, name, clsname, offset):
1085 'Emulate PyMemberDef in Include/structmember.h'
1086 # Also see descr_new() in Objects/descrobject.c
1087 self.name = name
1088 self.clsname = clsname
1089 self.offset = offset
1090
1091 def __get__(self, obj, objtype=None):
1092 'Emulate member_get() in Objects/descrobject.c'
1093 # Also see PyMember_GetOne() in Python/structmember.c
1094 return obj._slotvalues[self.offset]
1095
1096 def __set__(self, obj, value):
1097 'Emulate member_set() in Objects/descrobject.c'
1098 obj._slotvalues[self.offset] = value
1099
1100 def __repr__(self):
1101 'Emulate member_repr() in Objects/descrobject.c'
1102 return f'<Member {self.name!r} of {self.clsname!r}>'
1103
1104The :meth:`type.__new__` method takes care of adding member objects to class
1105variables. The :meth:`object.__new__` method takes care of creating instances
Raymond Hettinger80318772020-11-06 01:30:17 -08001106that have slots instead of an instance dictionary. Here is a rough equivalent
Raymond Hettinger74fa4642020-11-01 18:02:37 -08001107in pure Python::
1108
1109 class Type(type):
1110 'Simulate how the type metaclass adds member objects for slots'
1111
1112 def __new__(mcls, clsname, bases, mapping):
1113 'Emuluate type_new() in Objects/typeobject.c'
1114 # type_new() calls PyTypeReady() which calls add_methods()
1115 slot_names = mapping.get('slot_names', [])
1116 for offset, name in enumerate(slot_names):
1117 mapping[name] = Member(name, clsname, offset)
1118 return type.__new__(mcls, clsname, bases, mapping)
1119
1120 class Object:
1121 'Simulate how object.__new__() allocates memory for __slots__'
1122
1123 def __new__(cls, *args):
1124 'Emulate object_new() in Objects/typeobject.c'
1125 inst = super().__new__(cls)
1126 if hasattr(cls, 'slot_names'):
1127 inst._slotvalues = [None] * len(cls.slot_names)
1128 return inst
1129
1130To use the simulation in a real class, just inherit from :class:`Object` and
1131set the :term:`metaclass` to :class:`Type`::
1132
1133 class H(Object, metaclass=Type):
1134
1135 slot_names = ['x', 'y']
1136
1137 def __init__(self, x, y):
1138 self.x = x
1139 self.y = y
1140
1141At this point, the metaclass has loaded member objects for *x* and *y*::
1142
1143 >>> import pprint
1144 >>> pprint.pp(dict(vars(H)))
1145 {'__module__': '__main__',
1146 'slot_names': ['x', 'y'],
1147 '__init__': <function H.__init__ at 0x7fb5d302f9d0>,
1148 'x': <Member 'x' of 'H'>,
1149 'y': <Member 'y' of 'H'>,
1150 '__doc__': None}
1151
1152When instances are created, they have a ``slot_values`` list where the
1153attributes are stored::
1154
1155 >>> h = H(10, 20)
1156 >>> vars(h)
1157 {'_slotvalues': [10, 20]}
1158 >>> h.x = 55
1159 >>> vars(h)
1160 {'_slotvalues': [55, 20]}
1161
1162Unlike the real ``__slots__``, this simulation does have an instance
1163dictionary just to hold the ``_slotvalues`` array. So, unlike the real code,
1164this simulation doesn't block assignments to misspelled attributes::
1165
1166 >>> h.xz = 30 # For actual __slots__ this would raise an AttributeError