From: kedra marbun on
On Jul 8, 5:10 pm, Gregory Ewing <greg.ew...(a)canterbury.ac.nz> wrote:
> kedra marbun wrote:
> > i wonder what are the reasons for
> > not passing the class on which the descriptor is attached to, what
> > pattern is encouraged by this?
>
> The same answer applies. It's assumed that you will be
> writing a custom piece of code for each attribute of
> each class, and giving each one its own descriptor.
>
> By the time you get to the get or set method of a
> descriptor, you've already dispatched on both the
> class and attribute name. There is not usually any
> point in funnelling things back into a single function
> and then dispatching on the class or name again.
> Passing the class or name would just add overhead that
> was unnecessary in the majority of use cases.
>
> --
> Greg

True, unnecessary overhead. this 'passing class' thing comes from,
IIRC, learning python 4ed by Mark Lutz, it's stated there that the 3rd
arg to __get__ is the class to which the descriptor instance is
attached

so if i want the host class, i should do it the way builtin
descriptors do (bind it manually)? for example,
type.__dict__['__getattribute__'].__class__ is wrapper_descriptor.
wrapper_descriptor has member __objclass__ pointing to instance of
types.MemberDescriptorType, which disallows set & del, get returns the
host class ('type' in this case)

***
about the 3rd arg of __get__
i guess py has chosen __get__(self, ins, cls) over __get__(self, ins)
to make it easier for decriptor-implementor to find out whether the
caller (the left-side operand of dot operator) is instance of obj on
which the descriptor obj is found or not

this conclusion is based on the fact that:
- it is only __get__ that receives the redundant class obj
- if the caller is a class obj & descriptor is found on obj that is in
its __mro__, the fetch is still routed to __get__: __get__(desc, None,
CLASS). this doesn't happen for __{set|delete}__

note that the builtin descriptors even allow their's __get__ to be
given only the instance (2nd arg):
object.__getattribute__.__get__(obj)

is it correct?
From: Gregory Ewing on
kedra marbun wrote:
> this 'passing class' thing comes from,
> IIRC, learning python 4ed by Mark Lutz, it's stated there that the 3rd
> arg to __get__ is the class to which the descriptor instance is
> attached

That's there so that the __get__ method of function
objects can return an unbound method when looked up
on a class rather than an instance of the class.

There is no corresponding use case for a class argument
to __set__ or __delete__, so they don't have one.

--
Greg