Could somebody _PLEASE_ explain what's going on here?

Quinn Dunkan quinn at mark.ugcs.caltech.edu
Fri Nov 3 15:09:14 EST 2000


On Fri, 3 Nov 2000 10:35:50 -0800, Steve Juranich
<sjuranic at condor.ee.washington.edu> wrote:
>Okay, I'm getting really frustrated here because I don't understand what's
>going on.  Up to this morning, I had a class called "Table" that responded
>very nicely to the "print" command.  Now, all of a sudden, it doesn't work. 
>
>I have made a change in the code.  I overloaded the '__getattr__' to the
>following:
>
>    # 
>    # 
>    # This deals with accessing options that may have not been defined
>    # in the options file.
>    def __getattr__(self, k):
>        try:
>            return self.__dict__[k]
>        except KeyError:
>            return None
>
>and now here's my __repr__ function:
...
>As you can see, "print t" pukes, while "print `t`" works.  Why is this
>broken now?  How do I fix it?

The normal object behaviour when asked for an attribute that doesn't exist is
to throw an AttributeError.  You changed that: now *all* attribute accesses
return something (maybe None).  So:

print t

calls str(t) to turn 't' into a string.  str() checks for a __str__ method
first, and aha! 't' has a __str__ method (it has *all* methods now), so it
calls it.  Unfortunately, 't's __str__ method == None, so it tries to call
None, and throws an error.  Backticks and repr() work because they call the
__repr__ function, which does exist and hence isn't handled by __getattr__.

Everyone gets nailed by __getattr__ once in a while.  It's very powerful.

Moral: if you fundamentally change the way attribute access works, expect
some things to break.  And be careful with __getattr__.  I recommend using a
'get' method instead:

    def get_option(self, k):
        return self.__dict__.get(k)



More information about the Python-list mailing list