this is the first time I write here, sorry if the message is unfocuessed or too long.
I was interested in understanding more about how objects'attributes are fetched when needed. So I read the Python 2.7 documentation titled "Data Model" here, I met __getattr__
and, in order to check whether I understood or not its behavior, I wrote these simple (and incomplete) string wrappers.
class OldStr:
def __init__(self,val):
self.field=val
def __getattr__(self,name):
print "method __getattr__, attribute requested "+name
class NewStr(object):
def __init__(self,val):
self.field=val
def __getattr__(self,name):
print "method __getattr__, attribute requested "+name
As you can see they are the same except for being an oldstyle vs newstyle classes. Since the quoted text says __getattr__
is "Called when an attribute lookup has not found the attribute in the usual places", I wanted to try a + operation on two instances of those classes to see what happened, expecting an identical behavior.
But the results I got puzzled me a little bit:
>>> x=OldStr("test")
>>> x+x
method __getattr__, attribute requested __coerce__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable
Good! I did not define a method for __coerce__
(although I was expecting a request for __add__
, nevermind :), so __getattr__
got involved and returned a useless thing. But then
>>> y=NewStr("test")
>>> y+y
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'NewStr' and 'NewStr'
Why this asymmetric behavior between __getattr__
in oldstyle classes and newstyle ones when using a built-in operator like +? Could someone please help me to understand what is going on, and what was my mistake in reading the documentation?
Thanks a lot, your help is strongly appreciated!