Dynamic attribute introspection

Neil Hodgson nhodgson at bigpond.net.au
Mon Aug 13 21:59:12 EDT 2001


   Python allows classes to define dynamic attributes with the __getattr__
and __setattr__ methods. This is useful in many circumstances, particularly
when proxying to external objects such as those accessed through object
brokers (COM, XPCOM, CORBA, ...), databases, and dynamically wrapped APIs.
However, there is no generic method for finding the attributes that are
available through this feature even though the set of attributes is often
known at runtime by the class.

   In PythonCard (a GUI building project), users can interact with the user
interface from the shell by typing expressions such as "entry.text =
'Woger'". When the user types the "." a list is displayed with the available
attributes and methods. It helps the user to include dynamic attributes as
well as static attributes. Within PythonCard, we could provide a special
case solution to this but it would be much more useful to define a mechanism
that could be provided by any library and then used by any of the
interactive shells. There are interactive shells provided by many of the
development environments such as PythonWin, PythonCard and Boa Constructor.
Development environments provide other tools such as inspectors that could
benefit from this feature and it may also be useful for other generic code.

   The convention recently added to PyCrust, the interactive shell used by
PythonCard, is to call a method called _getAttributeNames() on the object of
interest which, if defined, returns a list of dynamic attribute names. If it
is not defined, an AttributeError is raised by Python. The display of
dynamic attributes using this convention was also easily added to PythonWin.
PythonCard provides its side of the convention by defining a
_getAttributeNames method on those classes which can have dynamic
attributes.

   Several issues are still undecided. The name "_getAttributeNames" and the
number of underscores on the front is uncertain. At least one underscore
seems justified on the basis that this is not a part of the objects
'intentional' interface but part of its introspection interface. A second
underscore moves it into the language domain which should ensure there are
no clashes with already existing code.

   _getAttributeNames can be defined to either return only the attributes
directly available on an object (thus requiring base classes to be visited
to find the full set) or can be defined to return all dynamic attributes
defined by the object and by any base classes. My preference is for the
latter due to the possibility of a class hiding the dynamic attributes of
its base classes. The counterview is that most introspection code currently
traverses all base classes anyway and this makes it similar to dir.

   It may also prove useful to define a mechanism to provide doc strings for
dynamic attributes for display by development tools.

   On a procedural note, is defining a convention an appropriate subject for
a PEP?

   Neil







More information about the Python-list mailing list