Enumerating Classes in Modules
Jeff Shannon
jeff at ccvcorp.com
Thu Nov 18 22:00:01 EST 2004
Rob Snyder wrote:
>Just in case anyone "follows in my footsteps" and has the same problem I did
>- Jeff's answer is pretty much dead on. The only stumbling block I had was
>that the dir() returns a list of strings representating the name of the
>attributes, and includes things that are not class definitions (e.g.
>'--builtins--'). So two modifications are necessary:
>
>1 - use the getattr() function with each item returned by dir() to actually
>load the class object
>
>
Right. Forgot about that little detail. Oops. :)
>2 - use type() to determine if it really it really is a classobj
>
>For example:
>for modname in nameslist:
> plugins[modname] = __import__(modname)
> # ....
> for item in dir(plugins[modname]):
> try:
> a = getattr(plugins[modname],item)
> if (type(a).__name__ == 'classobj'):
> item.standard_method()
> except AttributeError:
> pass
>
>
Be aware that this will fail for new-style classes --
>>> class O(object):
... pass
...
>>> type(O)
<type 'type'>
>>> type(O).__name__
'type'
>>>
Unless your required-method name is something that *is* really common
(i.e. likely to be present in __builtins__ or in other modules imported
by the plugin module), you're probably better off not trying to check
the type. Attempting the lookup won't hurt anything, as long as you
catch the AttributeError.
>>> mymodule = __import__('StringIO')
>>> mymodule
<module 'StringIO' from 'C:\Python22\lib\StringIO.pyc'>
>>> dir(mymodule)
['EINVAL', 'StringIO', '__all__', '__builtins__', '__doc__', '__file__',
'__name__', 'test', 'types']
>>> for item in dir(mymodule):
... obj = getattr(mymodule, item)
... try:
... obj.plugin_init()
... except AttributeError:
... print "%s has no attribute 'plugin_init'" % item
...
EINVAL has no attribute 'plugin_init'
StringIO has no attribute 'plugin_init'
__all__ has no attribute 'plugin_init'
__builtins__ has no attribute 'plugin_init'
__doc__ has no attribute 'plugin_init'
__file__ has no attribute 'plugin_init'
__name__ has no attribute 'plugin_init'
test has no attribute 'plugin_init'
types has no attribute 'plugin_init'
>>>
So as long as you're fairly careful about selecting your method name,
there's no reason to bother with typechecking. And if you *do* need to
be more specific, then you're probably better off defining a specific
plugin_base class and requiring all plugin classes to inherit from it
(enforced with issubclass(), presumably).
>Again, thanks for the help. I apologize for clogging up people's
>newsreaders, I've just found it helpful when poeple post their conculsions
>with things, so I wanted to do the same.
>
>
Followups are definitely a good thing. :)
Jeff Shannon
Technician/Programmer
Credit International
More information about the Python-list
mailing list