Something annoying about method __set_name__ in descriptors

Dieter Maurer dieter at handshake.de
Tue Apr 21 12:32:01 EDT 2020


ast wrote at 2020-4-21 14:27 +0200:
> From python version 3.6, there is a useful new method
>__set_name__ which could be implemented in descriptors.
>
>This method is called after a descriptor is instantiated
>in a class. Parameter "name" is filled with the name
>of the attribute refering to the descriptor in the class

> ...
>But I discovered that __set_name__ is not called immediately
>after the execution of line "value = Descriptor()" but after
>all class code execution ...

I recently read the Python (3.9a5) documentation - and there
I found clearly expressed this behaviour (I no longer can
tell you exactly where I read this).

The reason comes from the implementation: when the descriptor
is instantiated, the name the instance is bound to is not yet known.
Class creation is complex in Python (details in the Python documentation):
first a so called "namespace" (a mapping from names to values) is constructed;
after this construction, the so called metaclass is called with
class name, bases, the constructed namespace and potentially additional
keyword arguments. It is the typical metaclass (`type`) which calls
`__set_name__` for descritors it finds in the namespace.

This has several ramifications:

 * `__set_name__` is not called "inline" (as you observed)

 * `__set_name__` is not called automatically for descriptors added
   after class construction

 * `__set_name_` may not be called at all if the class uses
   a custom metaclass.


More information about the Python-list mailing list