Confusions about Python Descriptors and <Descriptor HowTo Guide> -
recently read official how-to python descriptors, derives an essay written raymond hettinger long time ago. after reading several times, still confused parts of it. quote paragraphs, followed confusions , questions.
if instance’s dictionary has entry same name data descriptor, data descriptor takes precedence. if instance’s dictionary has entry same name non-data descriptor, dictionary entry takes precedence.
- is same class? precedence chain of class if dictionary has entry same name data/non-data descriptor?
for objects, machinery in
object.__getattribute__()transformsb.xtype(b).__dict__['x'].__get__(b, type(b)). implementation works through precedence chain gives data descriptors priority on instance variables, instance variables priority on non-data descriptors, , assigns lowest priority__getattr__()if provided.for classes, machinery in
type.__getattribute__()transformsb.xb.__dict__['x'].__get__(none, b).
- the above 2 paragraphs tell process of descriptor's being invoked automatically upon attribute access. lists difference between attribute's being accessed instance (
b.x) , class (b.x). however, here confusions:- if attribute of class or instance not descriptor, transformation (i.e., transforms
b.xtype(b).__dict__['x'].__get__(b, type(b)),b.xb.__dict__['x'].__get__(none, b)) still proceed? returning attribute in class's or instance's dict directly simpler? - if instance's dictionary has entry same name non-data descriptor, according precedence rule in first quote, dictionary entry takes precedence, @ time transformation still proceed? or return value in dict?
- if attribute of class or instance not descriptor, transformation (i.e., transforms
non-data descriptors provide simple mechanism variations on usual patterns of binding functions methods.
- is non-data descriptors chosen because functions/methods can gotten, cannot set?
- what's underlying mechanism binding functions methods? since class dictionaries store methods functions, if call same method using class , instance respectively, how can underlying function tell whether first argument should self or not?
functions have
__get__()method can converted method when accessed attributes. non-data descriptor transformsobj.f(*args)callf(obj, *args). callingklass.f(*args)becomes f(*args).
- how can non-data descriptor transform
obj.f(*args)callf(obj, *args)? - how can non-data descriptor transform
klass.f(*args)callf(*args)? - what's underlying mechanism of above 2 transformations? why differences exist between class , instance?
- what role
__get__()method play under above circumstance?
is same class? precedence chain of class if dictionary has entry same name data/non-data descriptor?
no, if attribute defined both in superclass , subclass, superclass value ignored.
if attribute of class or instance not descriptor, transformation (i.e., transforms b.x
type(b).__dict__['x'].__get__(b, type(b)), b.xb.__dict__['x'].__get__(none, b))still proceed?
no, returns directly object gotten class's __dict__. or equivalently, yes, if pretend objects have default method __get__() ignores arguments , returns self.
if instance's dictionary has entry same name non-data descriptor, according precedence rule in first quote, dictionary entry takes precedence, @ time transformation still proceed? or return value in dict?
what not clear in paragraph quoted (maybe it's written down elsewhere) when b.x decides return b.__dict__['x'], no __get__ invoked in case. __get__ invoked when syntax b.x or b.x decides return object lives in class dict.
is non-data descriptors chosen because functions/methods can gotten, cannot set?
yes: generalization of "old-style" class model in python, in can b.f = 42 if f function object living in class b. lets function object overriden unrelated object. data descriptors on other hand have different logic in order support property.
what's underlying mechanism binding functions methods? since class dictionaries store methods functions, if call same method using class , instance respectively, how can underlying function tell whether first argument should self or not?
to understand this, need have "method objects" in mind. syntax b.f(*args) equivalent (b.f)(*args), 2 steps. first step calls f.__get__(b); returns method object stores both b , f. second step calls method object, in turn call original f adding b argument. doesn't occur b.f, because b.f, i.e. f.__get__(none, b), f (in python 3). it's way special method __get__ designed on function objects.
Comments
Post a Comment