__getattr__ question

L

Laszlo Nagy

Hello,

This is from the Python documentation (fragment):

__getattr__( self, name)
Called when an attribute lookup has not found the attribute in the
usual places (i.e. it is not an instance attribute nor is it found in
the class tree for self). name is the attribute name. This method should
return the (computed) attribute value or raise an AttributeError exception.


How can I determine if an attribute can be found in the usual places?
Here is an example program that will enlight the basic problem.

class TemplateItem(object):
def __init__(self,name):
self.name = name
self.items = [] # Order of items is important
def __getattr__(self,name):
"""I would like to access the items easily, with their name (if
possible)"""
for item in self.items:
if hasattr(item,'name') and item.name == name:
return item
raise AttributeError("%s: attribute or item does not exists."%name)
def __str__(self):
return "TemplateItem('%s')"%self.name

class CustomTemplateItem(TemplateItem):
pass # I could have been customized this...


root = CustomTemplateItem('root')
i1 = CustomTemplateItem('item1')
i2 = CustomTemplateItem('item2')

root.items.append(i1)
root.items.append(i2)
TemplateItem.item3 = TemplateItem('item3')

print root
print root.item1
print root.item2
print root.item3

Of course this program will print:

TemplateItem('root')
TemplateItem('item1')
TemplateItem('item2')
TemplateItem('item3')

So how can I tell if 'root.item3' COULD BE FOUND IN THE USUAL PLACES, or
if it is something that was calculated by __getattr__ ?
Of course technically, this is possible and I could give a horrible
method that tells this...
But is there an easy, reliable and thread safe way in the Python
language to give the answer?

Thanks,

Laszlo
 
B

Ben Cartwright

Laszlo said:
So how can I tell if 'root.item3' COULD BE FOUND IN THE USUAL PLACES, or
if it is something that was calculated by __getattr__ ?
Of course technically, this is possible and I could give a horrible
method that tells this...
But is there an easy, reliable and thread safe way in the Python
language to give the answer?

Why are you trying to do this in the first place? If you need to
distinguish between a "real" attribute and something your code returns,
you shouldn't mix them by defining __getattr__ to begin with.

If, as I suspect, you just want an easy way of accessing child objects
by name, why not rename "__getattr__" in your code to something like
"get"?

Then instead of
Alternately, make self.items an instance of a custom class with
__getattr__ defined. This way, root's attribute space won't be
cluttered up.
Either way is a few more characters to type, but it's far saner than
trying to distinguish between "real" and "fake" attributes.

--Ben
 
L

Laszlo Nagy

Either way is a few more characters to type, but it's far saner than
trying to distinguish between "real" and "fake" attributes.
I think you are right. I'll make up my mind.
 
G

gotletter

Hello!
How can I determine if an attribute can be found in the usual places?

print "item1" in dir(root) # False
print "item3" in dir(root) # True

Is it the behavior you wanted?
 
L

Laszlo Nagy

print "item1" in dir(root) # False
print "item3" in dir(root) # True

Is it the behavior you wanted?
Exactly. :) Why I did not think of this?

I'm always amazed when I see that Python can do anything we want. :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top