What happened in this class

Remco Gerlich scarblac at pino.selwerd.nl
Sun Dec 31 12:13:01 CET 2000

Emile van Sebille <emile at fenx.com> wrote in comp.lang.python:
> I saw Pearu's lazy extension and built and installed it on
> my linux system(recent cvs).  I thought I'd see how it
> played in a class vs getattr and got this result.  Thinking
> something broke along the way, I then switched over to the
> win95 system(2.0 #8), and got the same thing.  This doesn't
> happen under 1.52.
> class test:
>     def __getattr__(self, name):
>         return "egs"
> t = test()
> print dir(t)[1:5]
> ['e', 'g', 'g', 's']
> Now I know this is contrived, but I still didn't expect
> these results.  Should I have?

Real weird. dir(t) returns ['e', 'e', 'g', 'g', 's', 's']. It's pretty
simple to find out what it actually calls by adding another print

class test:
   def __getattr__(self, name):
      print name
      return "egs"
print dir(t)

['e', 'e', 'g', 'g', 's', 's']

So here we see that apparently dir() in 2.0 works by calling the __members__
and __methods__ special functions, and they both return "egs", and since
dir() was expecting a list it reads that as ['e','g','s'], adds them
together, and sorts them.

These special functions are *not* documented in chapter 3 of the 2.0
language reference and I suppose that is wrong. They don't look like the
sort of thing you would want to change though. Or maybe they can be useful,
if you define a data member by means of __getattr__ but you still want it
to show up in dir(). Needs docs.

In conclusion, making a __getattr__ that returns something completely
regardless of the name you put in is not a good idea :-)

Remco Gerlich

More information about the Python-list mailing list