How to customize getattr(obj, prop) function ?

bruno at modulix onurb at xiludom.gro
Thu May 18 04:58:05 EDT 2006


Pierre wrote:
> Hi,
> 
> Sorry in advance, english is not my main language :/
> 
> I'd like to customize the result obtained by getattr on an object : if
> the object has the requested property then return it BUT if the object
> doesn't has actually this property return something else.

So implement __getattr__(self, name).

> In my case, I can't use getattr(object, property, default_value).

Why so ?

> 
> I tried to write a class with a __getattr__ method and even a
> __getattribute__ method but this doesn't do what I want....

Warning: __getattribute__ will take over normal attribute lookup. It can
be really tricky. Anyway, you don't need it for your use case - just
stick with __getattr__() and you'll be ok.

> Maybe I didn't correctly understand this :
> http://docs.python.org/ref/attribute-access.html
> 
> Here is a piece of my code :
> =====================================
> class myclass:

Make this :
class MyClass(object):


>     """docstring"""
> 
>     a = 'aa'
>     b = 'bb'

a and b are class attributes, not instance attributes. If you want
per-instance attributes (which is the most usual case...), you need to
define them in a method - usually the __init__() method:

     def __init__(self):
        self.a = 'aa'
        self.b = 'bb'

>     def __getattr___(self, ppt):
>         """getattr"""
>         if hasattr(self, ppt):
>             return self.ppt

__getattr__() will be called only if the  normal attribute lookup fails.
 So calling hasattr(self, ...) in __getattr__ is useless. More than
this: the fact that __getattr__() has benn called means that normal
lookup has already failed, so hasattr() will end up calling
__getattr__()...

>         else:
>             return "my custom computed result"





(snip)

> 
> if __name__ == "__main__":
> 
>     d = myclass()
>     p1 = getattr(d, "a")

You do understand that getattr(d, "a") is the same as d.a, don't you ?

>     print p1
>     p2 = getattr(d, "b")
>     print p2
>     p3 = getattr(d, "c")
>     print p3
> ================================
> 
> I get an AttributeError when accessing to the property named "c".
> 
> Any explanation/solution to my problem ?

1/ use new-style classes
2/ only implement __getattr__()


here's a minimal working example:

class MyClass(object):
  def __init__(self, default='default'):
    self.a = 'aa'
    self.b = 'bb'
    self._default = default

  def __getattr__(self, name):
    return self._default

m = MyClass()
m.a
m.b
m.toto

HTH
-- 
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"



More information about the Python-list mailing list