Thanks, Peter. I realize this is getting sort of academic now, as I know how to do exactly what I want, but I'm still confused. Is __getattr__ a special case then, even for classic classes?
class Adder(): # python 2.7, classic class def __init__(self, x): self.x = x self.__add__= lambda other: Adder(self.x+other.x) self.__getattr__ = lambda name: self.test(name) def __str__(self): return str(self.x) def test(self, name): print("Hello from test") raise AttributeError x = Adder(3) y = Adder(4) print(x+y) x.junk() 7 Traceback (most recent call last): File "C:\Users\Saul\Documents\PythonProjects\test.py", line 18 AttributeError: Adder instance has no attribute 'junk' Why does this work for __add__ and not for __getattr__? Of course, they both work if I write instead def __add__self, other): return Adder(self.x+other.x) def __getattr__(self, name): print(name) raise AttributeError like a sensible person. Saul On Monday, February 4, 2013 8:15:47 AM UTC-6, Peter Otten wrote: > Saul Spatz wrote: > > > > > Now I have another question. If dunder methods are looked up only in the > > > class, not the instance, why did defining __nonzero__ the way I did work? > > > Shouldn't I have had to define it with a def? Is __nonzero__ a special > > > case? > > > > Unfortunately the situation is a bit more complex. Classic classes (like > > Tkinter.Frame) behave differently from newstyle classes (subclasses of > > object): > > > > >>> def nz(): > > ... print "nonzero" > > ... return 0 > > ... > > >>> class Classic: pass > > ... > > >>> c = Classic() > > >>> c.__nonzero__ = nz > > >>> not c > > nonzero > > True > > >>> class New(object): pass > > ... > > >>> n = New() > > >>> n.__nonzero__ = nz > > >>> not n > > False > > > > So Steven is wrong here. > > > > > Shouldn't I have had to define it with a def? > > > > If you mean as opposed to a lambda, there is no difference between > > > > f = lambda ... > > > > and > > > > def f(...): ... > > > > other than that the last one gives you a nice name in a traceback. -- http://mail.python.org/mailman/listinfo/python-list