The Python Oracle

What kind of python magic does dir() perform with __getattr__?

--------------------------------------------------
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: Breezy Bay

--

Chapters
00:00 What Kind Of Python Magic Does Dir() Perform With __getattr__?
01:57 Accepted Answer Score 12
03:28 Thank you

--

Full question
https://stackoverflow.com/questions/2756...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #python27

#avk47



ACCEPTED ANSWER

Score 12


There are two deprecated attributes in Python 2, object.__members__ and object.__methods__; these were aimed at supporting dir() on extension types (C-defined objects):

object.__methods__
Deprecated since version 2.2: Use the built-in function dir() to get a list of an object’s attributes. This attribute is no longer available.

object.__members__
Deprecated since version 2.2: Use the built-in function dir() to get a list of an object’s attributes. This attribute is no longer available.

These were removed from Python 3, but because your connection object (at leasts in the older version you are using) still provides a __methods__ attribute that is found through your __getattr__ hook and used by dir() here.

If you add a print statement to the __getattr__ method you'll see the attributes being accessed:

>>> class Wrapper(object):
...     def __init__(self, obj):
...         self._wrapped_obj = obj
...     def __getattr__(self, obj):
...         print 'getattr', obj
...         return getattr(self._wrapped_obj, attr)
... 
>>> dir(Wrapper({}))
getattr __members__
getattr __methods__
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_wrapped_obj']

For new-style objects, the newer __dir__ method supported by dir() is properly looked up on the type only so you don't see that being accessed here.

The project HISTORY file suggests the attributes were removed in the big Python 3 compatibility update for 1.2.4 beta 1.