Finding source from class or instance?

Alex Martelli aleaxit at yahoo.com
Thu Jan 18 04:42:32 EST 2001


"Stuart Stanley" <stuarts at 171.69.180.197> wrote in message
news:979777210.145620 at sj-nntpcache-5...
>
>
> Folks,
>
> Is there a (easy!) way to get the source code from a class or instance
> of a class?  A preference would lie in just getting the source of the
> base class itself, but I would settle for getting the file name where
> the base class lives in.  I figure the information is sitting in the
> modules somewhere, but I don't know how to navigate there to get it....

A class object has an attribute __module__ which identifies the *name*
of the module in which the class was defined; from an instance object,
you can get its class object via its attribute __class__ (I'm not
sure where 'the base class' comes in, but if you need a class's bases
you'll want to look at the class object's attribute __bases__ which
just lists them in order -- these are class objects, not names).

Given the module name, you may look for the module object in
dictionary sys.modules; if you do find it (it _could_ have been
removed in the meantime), it MAY have an attribute __file__ which
gives the path to the file the module was loaded from IF it was
indeed loaded from a file (it need not have been).

For 'normal' cases, then, something like:

theclass = instance.__class__
modname = theclass.__module__
import sys
modobj = sys.modules[modname]
thepath = modobj.__file__

may give you what you want (or rather, what you would settle for).
Just make sure you trap all the possible exceptions and anomalies
at each step!

The file named by thepath may not be around any more, of course --
it may have been erased or renamed just after it was compiled to
a .pyc or .pyo, for example.  Or, if it exists, it need not be
the same as it was back when the class definition was executed
(it may have been overwritten, and who can tell what differences
may have been caused by such overwriting!).


There is a dis module, that does 'disassembly' of bytecode, but
that's lower-level than the Python source you seek, and also
seems to apply only to _methods_ defined in a class rather than
to the code in the classbody itself (offhand, I don't know how
to get to the codeobject for the latter -- anybody...?).


Alex






More information about the Python-list mailing list