471,350 Members | 1,609 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

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

__getattr__ weirdness

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 trials, I added
some print statements to debug stuff. The ones I added to __setattr__
work as expected, but the one in __getattr__ seems to get called just
under 1000 times for every __getattr__ call!

Something is obviously not right here - but I'm at a loss to understand
what's going on. I've pared down my code to still show it happening &
included it below. If you run this program & pipe the output to a file,
you'll get just under 14000 debug lines. Any ideas? Thanks!

--
Greg
# ----------------------------------------------------------------------
----------
class test:
"""Introspection test"""

#----------------------------------------
def __init__(self,filename):
print '** __init__'
self._filename=filename
self._del=' '
self._dirty=False
self._open=False
self._rec=[]
self._recno = 1

#----------------------------------------
def __getattr__(self, key):
""" Return DBF record values by field name """
print "_ga: " + key
try:
return self._rec[self._fldNames.index(key.upper())]
except:
raise AttributeError("Unknown Field: %s" % ( key ))

#----------------------------------------
def __setattr__(self, key, val):
""" Update DBF record values by field name """
print "_sa: %s: %s" % (key, val)
try:
self._rec[self._fldNames.index(key.upper())] = val
print " (DBF field assignment)"
except:
self.__dict__[key] = val # use the regular variable!
#raise AttributeError("Unknown Field: %s" % ( key ))

#----------------------------------------
#----------------------------------------
if __name__ == "__main__":

f = test('test.dbf')
f._del='*'
f._recno=123
f._recno=1
f._recno=2
f._recno=3
f._recno=4
f._recno=5
f._recno=6

Jul 18 '05 #1
3 3254
I've figured out one thing: that be re-arranging the __init__ code
assignments (and adding one that was placed later in code I snipped
out), I am able to get the extra _ga calls to stop a lot earlier. This
code:

#----------------------------------------
def __init__(self,filename):
print '** __init__'
self._rec=[]
self._fldNames=[]
self._filename=filename
self._del=' '
self._dirty=False
self._open=False
self._recno = 1

.... by assigning _rec & _fldNames first, gets the repeated _ga calls to
stop after the first assignment following those two assignments. I'm
still at a loss as to why _ga is being called all these times to begin
with though! I'm only assigning values, not requesting them! Thanks,

--
Greg

Jul 18 '05 #2
Greg Brunet wrote:
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 trials, I added
some print statements to debug stuff. The ones I added to __setattr__
work as expected, but the one in __getattr__ seems to get called just
under 1000 times for every __getattr__ call!

Something is obviously not right here - but I'm at a loss to understand
what's going on. I've pared down my code to still show it happening &
included it below. If you run this program & pipe the output to a file,
you'll get just under 14000 debug lines. Any ideas? Thanks!


Within the __getattr__ method, you can't just do normal attribute access as
this will trigger another call to __getattr__, so you where stuck in an
infinite loop.
try to access the required attribute directly from the __dict__

def __getattr__(self, key):
""" Return DBF record values by field name """
print "_ga: " + key
try:
# return self._rec[self._fldNames.index(key.upper())]
^^^^
return self.__dict__['_rec'][self._fldNames.index(key.upper())]
except:
raise AttributeError("Unknown Field: %s" % ( key ))

Hope that helps

Stephan
Jul 18 '05 #3
"Stephan Diehl" <st***********@gmx.net> wrote in message
news:bi*************@news.t-online.com...
Within the __getattr__ method, you can't just do normal attribute access as this will trigger another call to __getattr__, so you where stuck in an infinite loop.
try to access the required attribute directly from the __dict__

def __getattr__(self, key):
""" Return DBF record values by field name """
print "_ga: " + key
try:
# return self._rec[self._fldNames.index(key.upper())]
^^^^
return self.__dict__['_rec'][self._fldNames.index(key.upper())] except:
raise AttributeError("Unknown Field: %s" % ( key ))

Hope that helps

Stephan


Hey Stephan:

That did the trick! Actually, I had to do the same for self._fldNames
as well. Also, I changed them in the _sa code section instead of the
_ga code, since now that I look at it again with a little better
understanding, the original _sa code was referring to the _rec &
_fldNames variables/attributes directly, so as long as they weren't
defined, it was triggering the _ga calls. So now the _ga code doesn't
get called unless I specifically ask for it - like I would want. The
code now looks like:

#----------------------------------------
def __getattr__(self, key):
""" Return DBF record values by field name """
print "_ga: " + key
try:
return self._rec[self._fldNames.index(key.upper())]
except:
raise AttributeError("Unknown Field: %s" % ( key ))

#----------------------------------------
def __setattr__(self, key, val):
""" Update DBF record values by field name """
print "_sa: %s: %s" % (key, val)
try:

self.__dict__['_rec'][self.__dict__['_fldNames'].index(key.upper())] =
val
print " (DBF field assignment)"
except:
self.__dict__[key] = val # use the regular variable!
#raise AttributeError("Unknown Field: %s" % ( key ))

Thanks for everyone's help!

--
Greg
Jul 18 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by Holger Joukl | last post: by
3 posts views Thread by Chris Curvey | last post: by
reply views Thread by Gigi | last post: by
13 posts views Thread by Pelmen | last post: by
6 posts views Thread by Erik Johnson | last post: by
2 posts views Thread by Peter Bengtsson | last post: by
4 posts views Thread by Enrico | last post: by
7 posts views Thread by =?UTF-8?Q?Alexandru_Mo=C8=99oi?= | last post: by
reply views Thread by XIAOLAOHU | last post: by

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.