473,554 Members | 3,084 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Inconsistent behavior of descriptors


I've noticed that the order of attribute lookup is inconsistent
when descriptor is used. property instance takes precedence of
instance attributes:
class A(object): .... def _get_attr(self) :
.... return self._attr
.... attr = property(_get_a ttr)
.... a=A()
a.__dict__ {} a.__dict__['attr']=1
a.__dict__ {'attr': 1} a.attr Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in _get_attr
AttributeError: 'A' object has no attribute '_attr'

But it doesn't when I use custom class of descriptor:
class descr(object): .... def __get__(self, inst, cls):
.... return inst._attr
.... class B(object): .... attr = descr()
.... b=B()
b.__dict__ {} b.__dict__['attr']=1
b.__dict__ {'attr': 1} b.attr 1

Subclasses of property behave like property itself:
class descr2(property ): .... def __get__(self, inst, cls):
.... return inst._attr
.... class C(object): .... attr = descr2()
.... c=C()
c.__dict__ {} c.__dict__['attr']=1
c.__dict__ {'attr': 1} c.attr

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in __get__
AttributeError: 'C' object has no attribute '_attr'

Is it an undocumented feature or I have to submit a bug report?

--
Denis S. Otkidach
http://www.python.ru/ [ru]
Jul 18 '05 #1
2 1898

"Denis S. Otkidach" <od*@strana.r u> wrote in message
news:ma******** *************** ***********@pyt hon.org...

I've noticed that the order of attribute lookup is inconsistent
when descriptor is used. property instance takes precedence of
instance attributes:
class A(object): ... def _get_attr(self) :
... return self._attr
... attr = property(_get_a ttr)
... a=A()
a.__dict__ {} a.__dict__['attr']=1
a.__dict__ {'attr': 1} a.attr Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in _get_attr
AttributeError: 'A' object has no attribute '_attr'

But it doesn't when I use custom class of descriptor:
class descr(object): ... def __get__(self, inst, cls):
... return inst._attr
... class B(object): ... attr = descr()
... b=B()
b.__dict__ {} b.__dict__['attr']=1
b.__dict__ {'attr': 1} b.attr 1

Subclasses of property behave like property itself:
class descr2(property ): ... def __get__(self, inst, cls):
... return inst._attr
... class C(object): ... attr = descr2()
... c=C()
c.__dict__ {} c.__dict__['attr']=1
c.__dict__ {'attr': 1} c.attr
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in __get__
AttributeError: 'C' object has no attribute '_attr'

Is it an undocumented feature or I have to submit a bug report?


I'm not entirely sure what you're describing, however, I
notice that your descriptor object has a __get__ method,
but no __set__ or __del__ methods. The lookup chain
is quite different for descriptors with only __get__ methods
than it is for descriptors for all three.

In particular, it's intended that instance attributes should
be ignored if there is a data descriptor (that is, a descriptor
with both__get__ and __set__ methods.)

I'm not sure if this applies to your problem.

John Roth
--
Denis S. Otkidach
http://www.python.ru/ [ru]

Jul 18 '05 #2
On Tue, 30 Sep 2003 20:15:10 +0400 (MSD), "Denis S. Otkidach" <od*@strana.r u> wrote:

I've noticed that the order of attribute lookup is inconsistent
when descriptor is used. property instance takes precedence of
instance attributes:
class A(object):... def _get_attr(self) :
... return self._attr
... attr = property(_get_a ttr)
... a=A()
a.__dict__{} a.__dict__['attr']=1
a.__dict__{'attr': 1} a.attrTraceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in _get_attr
AttributeError : 'A' object has no attribute '_attr'

But it doesn't when I use custom class of descriptor:
class descr(object):... def __get__(self, inst, cls):
... return inst._attr
... class B(object):... attr = descr()
... b=B()
b.__dict__{} b.__dict__['attr']=1
b.__dict__{'attr': 1} b.attr1

Subclasses of property behave like property itself:
class descr2(property ):... def __get__(self, inst, cls):
... return inst._attr
... class C(object):... attr = descr2()
... c=C()
c.__dict__{} c.__dict__['attr']=1
c.__dict__{'attr': 1} c.attr

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in __get__
AttributeError : 'C' object has no attribute '_attr'

Is it an undocumented feature or I have to submit a bug report?

I think (not having read the above carefully) that it's all documented in

http://users.rcn.com/python/download/Descriptor.htm

(thanks to Raymond Hettinger).

excerpt:
"""
The details of invocation depend on whether obj is an object or a class.
Either way, descriptors only work for new style objects and classes. A
class is new style if it is a subclass of object.

For objects, the machinery is in object.__getatt ribute__ which
transforms b.x into type(b).__dict_ _['x'].__get__(b, type(b)). The
implementation works through a precedence chain that gives data
descriptors priority over instance variables, instance variables
priority over non-data descriptors, and assigns lowest priority to
__getattr__ if provided. The full C implementation can be found in
PyObject_Generi cGetAttr() in Objects/object.c.

For classes, the machinery is in type.__getattri bute__ which transforms
B.x into B.__dict__['x'].__get__(None, B). In pure Python, it looks
like:

def __getattribute_ _(self, key):
"Emulate type_getattro() in Objects/typeobject.c"
v = object.__getatt ribute__(self, key)
if hasattr(v, '__get__'):
return v.__get__(None, self)
return v

The important points to remember are:

descriptors are invoked by the __getattribute_ _ method
overriding __getattribute_ _ prevents automatic descriptor calls
__getattribute_ _ is only available with new style classes and objects
object.__getatt ribute__ and type.__getattri bute__ make different calls to __get__.
data descriptors always override instance dictionaries.
non-data descriptors may be overridden by instance dictionaries.
"""

Regards,
Bengt Richter
Jul 18 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
1802
by: François Pinard | last post by:
This question is a bit technical, but hopefully, this list will offer me good hints or nice solutions. Happily enough for me, it often does! :-) I would need to recognise and play with descriptor types, like: member descriptors method descriptors getset descriptors wrapper descriptors
1
2084
by: bk_kl | last post by:
Hi, I think the following behavior of the build in function 'split' is inconsistent. What do you think? >>> "".split() >>> "".split(";")
14
1625
by: Antoon Pardon | last post by:
Can anyone explain why descriptors only work when they are an attribute to an object or class. I think a lot of interesting things one can do with descriptors would be just as interesting if the object stood on itself instead of being an attribute to an other object. So what are the reasons for limiting this feature in such a way? --...
6
5953
by: Samuel M. Smith | last post by:
I have been playing around with a subclass of dict wrt a recipe for setting dict items using attribute syntax. The dict class has some read only attributes that generate an exception if I try to assign a value to them. I wanted to trap for this exception in a subclass using super but it doesn't happen. I have read Guido's tutorial on new...
20
2587
by: Francine.Neary | last post by:
I am learning C, having fun with strings & pointers at the moment! The following program is my solution to an exercise to take an input, strip the first word, and output the rest. It works fine when you give it 2 or more words, but when there's only 1 word the results vary depending on whether it's on Windows or Linux: under MSVC it displays...
9
1508
by: Lie | last post by:
I've noticed some oddly inconsistent behavior with int and float: Python 2.5.1 (r251:54863, Mar 7 2008, 03:39:23) on linux2 -345 works, but Traceback (most recent call last): File "<stdin>", line 1, in <module>
6
1312
by: Kai-Uwe Bux | last post by:
Juha Nieminen wrote: I think your code violates the One-Definition-Rule. The template function foo() is defined in two significantly different ways in the two files. As far as I know, no diagnostic is required for such errors.
8
1160
by: Michele Petrazzo | last post by:
Hi all, I want to modify the method that set use for see if there is already an object inside its obj-list. Something like this: class foo: pass bar1 = foo() bar1.attr = 1 bar2 = foo() bar2.attr = 1
2
5416
by: DJ Dharme | last post by:
Hi all, I am writing a multi-threaded application in c++ running on solaris. I have a file which is updated by a single thread by appending data into the file and at same time the other threads are reading the content written into the file. Can anybody tell me is there a performance or any other gain (except for the multex locking) by using...
0
7570
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
8008
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
7854
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6113
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5411
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5133
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3525
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1992
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1107
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.