473,385 Members | 1,893 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

__getattr__ and recursion ?

hello,

I tried to find an easy way to add properties (attributes) to a number
of different components.
So I wrote a class, from which all these components are derived.
By trial and error I created the code below, which now works, but
there is one thing I don't understand:
in the line indicated with "<<== 1" I'm not allowed to use

for item in self.extra_getters :

because it will result in an infinite recursion.
But in the line indicated with "<<== 2" , I am allowed ...
.... why is this allowed ??

thanks,
Stef Mientki
# ************************************************** *********************
# ************************************************** *********************
class _add_attribs ( object ) :
def __init__ ( self ) :
self.extra_setters = {}
self.extra_getters = {}

def _add_attrib ( self, text, setter = None, getter = None ) :
if setter :
self.extra_setters [ text ] = setter
if getter :
self.extra_getters [ text ] = getter

# ************************************************** *******
# always called instead of the normal mechanism
# ************************************************** *******
def __setattr__ ( self, attr, value ) :
for item in self.extra_setters :
if item == attr :
self.extra_setters [ item ] ( value )
break
else :
self.__dict__[attr] = value

# ************************************************** *******
# only called when not found with the normal mechanism
# ************************************************** *******
def __getattr__ ( self, attr ) :
try :
for item in self.__dict__['extra_getters'] : <<== 1
if item == attr :
return self.extra_getters [ item ] ( ) <<== 2
except :
return []
# ************************************************** *********************

Jun 27 '08 #1
2 2652
Stef Mientki wrote:
hello,

I tried to find an easy way to add properties (attributes) to a number
of different components.
So I wrote a class, from which all these components are derived.
By trial and error I created the code below, which now works, but
there is one thing I don't understand:
in the line indicated with "<<== 1" I'm not allowed to use

for item in self.extra_getters :

because it will result in an infinite recursion.
But in the line indicated with "<<== 2" , I am allowed ...
... why is this allowed ??
When the instance is created

self.extra_setters = {}

in the __init__() method triggers

self.__setattr__("extra_setters", {})

which executes

for item in self.extra_setters:
# ...

in the __setattr__() method. Because at that point there is no extra_setters
attribute

self.__dict__["extra_setters"]

fails and self.__getattr__("extra_setters") is used as a fallback. Now as
__getattr__() contains a self.extra_getters attribute access and that
attribute doesn't exist either this again triggers

self.__getattr__("extra_getters") -- ad infinitum.

By the way, looping over a dictionary destroys its key advantage, O(1)
lookup. Use

# untested
if attr in self.extra_setters:
self.extra_setters[attr](value)
else:
self.__dict__[attr] = value

and something similar in __getattr__().

Peter
>
thanks,
Stef Mientki
# ************************************************** *********************
# ************************************************** *********************
class _add_attribs ( object ) :
def __init__ ( self ) :
self.extra_setters = {}
self.extra_getters = {}

def _add_attrib ( self, text, setter = None, getter = None ) :
if setter :
self.extra_setters [ text ] = setter
if getter :
self.extra_getters [ text ] = getter

# ************************************************** *******
# always called instead of the normal mechanism
# ************************************************** *******
def __setattr__ ( self, attr, value ) :
for item in self.extra_setters :
if item == attr :
self.extra_setters [ item ] ( value )
break
else :
self.__dict__[attr] = value

# ************************************************** *******
# only called when not found with the normal mechanism
# ************************************************** *******
def __getattr__ ( self, attr ) :
try :
for item in self.__dict__['extra_getters'] : <<== 1
if item == attr :
return self.extra_getters [ item ] ( ) <<== 2
except :
return []
# ************************************************** *********************
Jun 27 '08 #2
thanks Peter,

for your perfect explanation, and
By the way, looping over a dictionary destroys its key advantage, O(1)
lookup. Use

# untested
if attr in self.extra_setters:
self.extra_setters[attr](value)
else:
self.__dict__[attr] = value

and something similar in __getattr__().

yes, that's probably much better, have to get used to this Python behavior,
thanks,

cheers,
Stef

Jun 27 '08 #3

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

Similar topics

3
by: Greg Brunet | last post by:
In adding the ability to refer to field values using dbfFile.field notation, I learned how to use __getattr__ and __setattr__ . After some trial and error, I got it working. But as part of my...
1
by: Holger Joukl | last post by:
Hi there, please excuse my rather lengthy post. With introduction of the new style classes, something seems to have changed for __getattr__ hooks, even for classic classes: getattr.py: class...
0
by: Gigi | last post by:
Hi, In the Python documentation regarding __getattribute__ (more attribute access for new style classes) it is mentioned that if __getattribute__ is defined __getattr__ will never be called...
13
by: Pelmen | last post by:
How can I get rid of recursive call __getattr__ inside this method, if i need to use method or property of the class?
6
by: Erik Johnson | last post by:
Maybe I just don't know the right special function, but what I am wanting to do is write something akin to a __getattr__ function so that when you try to call an object method that doesn't exist,...
7
by: bearophileHUGS | last post by:
I have tried this, with Psyco it segfaults, and with Python 2.5 (on Win) hangs the interpreter, is it possible to improve the situation? class T(object): def __getattr__(self, x): dir(self)...
5
by: glomde | last post by:
Hi, I tried to write a decorator for that should be for methods but for some reasons it doens seem to work when you try to do it on the __getattr__ method in a class. Could anybody give some...
4
by: Enrico | last post by:
Hi there, I have the following situation (I tryed to minimize the code to concentrate on the issue): def __getattr__(self, name): print 'A.__getattr__' if name == 'a': return 1 raise...
7
by: =?UTF-8?Q?Alexandru_Mo=C8=99oi?= | last post by:
i'm facing the following problem: class Base(object): def __getattr__(self, attr): return lambda x: attr + '_' + x def dec(callable): return lambda *args: 'dec_' + callable(*args) class...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
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,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
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...

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.