[Tutor] @property for old style classes vs new style classes
eryk sun
eryksun at gmail.com
Fri Sep 16 02:31:35 EDT 2016
On Thu, Sep 15, 2016 at 9:48 PM, monikajg at netzero.net
<monikajg at netzero.net> wrote:
> But why var is in class __dict__?
> Does @property make it a class attribute?
An instance of `property` is a data descriptor, i.e. it implements the
__get__, __set__, and __delete__ methods of the descriptor protocol. A
non-data descriptor only implements __get__. Descriptors are
fundamental to the way attribute lookup works in Python. See the
descriptor howto guide:
https://docs.python.org/3/howto/descriptor.html
The above document paints a picture of attribute access that's not
really accurate at times. Also, the example code that attempts to
demonstrate type.__getattribute__ in terms of object.__getattribute__
is wrong. (It fails to search the __mro__ of the class, only the
metaclass. Also, what it's trying to do is fundamentally impossible.
You can't know whether object.__getattribute___ already evaluated a
descriptor that it found in the metaclass.)
Here's an overview of how object.__getattribute__ works:
* If a data descriptor is found in the class, call its __get__
method, passing it the instance and the class, and return the
result.
* Else if the instance has a dict and the name is found in it,
return the value from the instance dict.
* Else if a non-data descriptor is found in the class, call its
__get__ method, passing it the instance and the class, and
return the result.
* Else if a non-descriptor is found in the class, return it.
* Else raise AttributeError.
A class lookup searches the dicts of each class in the __mro__,
stopping on the first hit. Also, a type can define a __getattr__
fallback method, in which case the AttributeError raised by
__getattribute__ is ignored.
For type.__getattribute__, the class object in this case is handled as
an instance of the metaclass. The main difference compared to
object.__getattribute__ is in the second step, since the instance in
this case is a class. Instead of searching just the class dict, it
searches the dicts of each class in the __mro__. Also, if it finds a
descriptor in the class __mro__, it calls its __get__ method, passing
None for the instance.
More information about the Tutor
mailing list