Raymond Hettinger wrote: > Steven D'Aprano wrote: > > I came across this unexpected behaviour of getattr for new style classes. > > Example: > > > > >>> class Parrot(object): > > ... thing = [1,2,3] > > ... > > >>> getattr(Parrot, "thing") is Parrot.thing > > True > > >>> getattr(Parrot, "__dict__") is Parrot.__dict__ > > False > > > > I would have expected that the object returned by getattr would be the > > same object as the object returned by standard attribute access. > > The returned object is a wrapper created on-the-fly as needed. You've > requested two of them and each wrapper has a different object id but > wraps an identical source. > > Contemplate this for a bit: > > >>> class Parrot(object): > thing = [1,2,3] > def f(self): pass > > >>> getattr(Parrot, 'f') is getattr(Parrot, 'f') > False > >>> getattr(Parrot, '__dict__') is getattr(Parrot, '__dict__') > False
Yes, in fact getattr has nothing to do with it. To wit: >>> Parrot.f is Parrot.f False >>> Parrot.__dict__ is Parrot.__dict__ False But wait, it gets weirder. >>> id(Parrot.f) == id(Parrot.f) True >>> id(Parrot.__dict__) == id(Parrot.__dict__) True But that's not all. Redefine Parrot as: class Parrot(object): def f(self): pass def g(self): pass Then, >>> id(Parrot.f) == id(Parrot.g) True your-milage-may-vary-ly yr's, Carl Banks -- http://mail.python.org/mailman/listinfo/python-list