Message16343
Logged In: YES
user_id=589306
I did some research and thinking on this problem, and here
is what I think is happening.
1. When you print self inside __getattr__, Python calls
repr(self) to figure out how to print that.
2. repr(self) attempts to call self.__repr__().
3. Since you didn't define __repr__ for this class,
__getattr__ is called to look up the name.
4. __getattr__ attempts to print self again, and you are now
in an infinite loop.
For more information, do a Google Groups search for "Obscure
__getattr__ behavior" which should bring you to the thread
at http://tinyurl.com/ecsh (hope that works, heh). It even
mentions the difference bcannon mentioned between old and
new style classes.
You could solve the problem by defining your own __repr__
(and __str__ for similar reasons). Or you can raise
AttributeError in __getattr__ if name is __repr__ or __str__
so that Python reverts back to defaults for these functions.
Here is a way to write your class so that it does what you want:
>>> class B:
... def __getattr__(self, name):
... if name == '__repr__' or name == '__str__':
... raise AttributeError
... print self, name
... return 3
...
>>> b = B()
>>> b.c
<__main__.B instance at 0x81c785c> c
3
I'm leaning toward the opinion that the infinite loop
behavior is not a bug in Python. Even though the result
wasn't expected, Python was doing exactly as told.
However, the Segmentation Fault you got on your system is
probably a bug. That seems related to your OS / build of
Python though. Can anyone duplicate the segfault?
Maybe Python isn't catching the infinite recursion fast
enough and your stack is overflowing (just a wild guess).
Try running some code like this and see if you get a
RuntimeError or a segfault:
def f():
f()
Then call f() to see what error you get.
|
|
Date |
User |
Action |
Args |
2007-08-23 14:13:51 | admin | link | issue752221 messages |
2007-08-23 14:13:51 | admin | create | |
|