Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #110958
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Newsgroups | comp.lang.python |
| Subject | Re: Descriptor: class name precedence over instance name |
| Date | 2016-07-02 07:55 -0600 |
| Message-ID | <mailman.25.1467467750.2295.python-list@python.org> (permalink) |
| References | <nl7frv$t48$1@dont-email.me> <85shvstze5.fsf@benfinney.id.au> <mailman.11.1467435171.2295.python-list@python.org> <nl81ro$hp1$1@dont-email.me> <CALwzidkkqTFEzEYQnVaScUq9+Dee035tijZQVu3cF2G=JotOGQ@mail.gmail.com> |
On Sat, Jul 2, 2016 at 3:34 AM, Veek. M <vek.m1234@gmail.com> wrote:
> So essentially from what Ian said:
> data_descriptor_in_instance -> instance_attribute -> non-
> data_descriptor_in_instance -->__mro__
>
> is how the search takes place. Correct?
Close, but I would write it as:
data_descriptor_in_class_including_mro -> instance_attribute ->
non_data_descriptor_or_class_attribute_including_mro
In either case the class dict search is in __mro__ order. You can find
the actual implementation here:
https://hg.python.org/cpython/file/30099abdb3a4/Objects/object.c#l1326
Roughly, the algorithm is this:
tp = type(obj)
# This call searches the MRO.
descr = _PyType_Lookup(tp, name)
if descr != NULL and is_data_descriptor(descr):
return descr.__get__(obj, tp)
if name in obj.__dict__:
return obj.__dict__[name]
if descr != NULL and is_non_data_descriptor(descr):
return descr.__get__(obj, tp)
if descr != NULL:
return descr
raise AttributeError(name)
> ------------------------------
>
> Regarding part2 of the Q, :) Ian hasn't explained it, so I'm not sure
> how to explain it better :) but i'll try given that he has clarified
> part of the answer.
>
> Basically Beazley has a TypedProperty descriptor class, and in class Foo
> he instantiates:
> name = TypedProperty
> Then he does f = Foo()
>
> Thanks to Ian, we now know that any lookup on 'f' eg: f.name would
Not *any* lookup, only one for which there is a declared descriptor.
So in this example f.name or f.num would resolve according to the
descriptor's __get__ method, but any other attribute lookup would just
return whatever value is set on the instance (if any).
> cause.. well.. the f.name(TypedProperty-descriptor) to gain precedence
> thus hiding the f.name attribute! Therefore he needs to name-decorate or
> in this example append an '_' for whatever stupid reason.
Right, if the "name" descriptor tried to store the value in the
unmangled "name" instance attribute, then its getattr call would just
recur back to the descriptor and you'd have an infinite loop.
In my opinion the mangling should be a bit heavier than what's done in
this example, to avoid collisions between the descriptor and the class
that's using it. I like to follow the pattern of __foo name mangling,
so I would have instead used:
self.name = "_TypedProperty__" + name
Back to comp.lang.python | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Descriptor: class name precedence over instance name "Veek. M" <vek.m1234@gmail.com> - 2016-07-02 09:57 +0530
Re: Descriptor: class name precedence over instance name Ian Kelly <ian.g.kelly@gmail.com> - 2016-07-01 22:51 -0600
Re: Descriptor: class name precedence over instance name Ben Finney <ben+python@benfinney.id.au> - 2016-07-02 14:52 +1000
Re: Descriptor: class name precedence over instance name "Veek. M" <vek.m1234@gmail.com> - 2016-07-02 15:04 +0530
Re: Descriptor: class name precedence over instance name Ian Kelly <ian.g.kelly@gmail.com> - 2016-07-02 07:55 -0600
Re: Descriptor: class name precedence over instance name "Veek. M" <vek.m1234@gmail.com> - 2016-07-03 20:19 +0530
csiph-web