Unexpected behaviour of getattr(obj, __dict__)
Carl Banks
invalidemail at aerojockey.com
Tue Feb 14 07:31:47 EST 2006
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
More information about the Python-list
mailing list