Search code examples
pythonattributesdatamodelpython-descriptors

Why does __get__ take an owner while __set__ and __delete__ do not?


From the Python data model documentation:

object.__get__(self, instance, owner=None)

Called to get the attribute of the owner class (class attribute access) or of an instance of that class (instance attribute access). The optional owner argument is the owner class, while instance is the instance that the attribute was accessed through, or None when the attribute is accessed through the owner.

This method should return the computed attribute value or raise an AttributeError exception.

PEP 252 specifies that __get__() is callable with one or two arguments. Python’s own built-in descriptors support this specification; however, it is likely that some third-party tools have descriptors that require both arguments. Python’s own __getattribute__() implementation always passes in both arguments whether they are required or not.

object.__set__(self, instance, value)

Called to set the attribute on an instance instance of the owner class to a new value, value.

Note, adding __set__() or __delete__() changes the kind of descriptor to a “data descriptor”. See Invoking Descriptors for more details.

object.__delete__(self, instance)

Called to delete the attribute on an instance instance of the owner class.

Why does __get__ take an owner while __set__ and __delete__ do not?

Does it mean that when a descriptor supplies both __get__ and __set__,

  • we can get an attribute no matter whether it belongs to an instance of the owner class or to the owner class,
  • we can set and delete an attribute when it belongs to an instance of the owner class but not when it belongs to the owner class?

My question is actually part of this one.


Solution

  • owner mostly exists for getting the attribute on the class itself, rather than an instance. When you're retrieving the attribute on an instance, the owner argument is redundant, since it's just type(instance).

    __set__ doesn't apply to setting the attribute on the class itself, so it has no use for owner.