Iterate the classes defined in a module imported dynamically
I have a module from a child package that is imported dynamically; how can I iterate over the classes that it contains?
I have been importing the module and listing the names like this:
package = current_module.__name__
package = package[:package.rindex(".")] # get the package
package = "%s.sub.%s"%(package,name) # make the name of the child
print "(loading package %s)"%pack开发者_开发技巧age
module = __import__(package) # this succeeds
for name,obj in inspect.getmembers(module):
print name,type(obj)
This only prints module attributes and not the class types that the module defines:
__builtins__ <type 'dict'>
__doc__ <type 'NoneType'>
__file__ <type 'str'>
__name__ <type 'str'>
__package__ <type 'NoneType'>
__path__ <type 'list'>
imported_package <type 'module'>
It seems that my classes are not in the __dict__
unless the fromlist
is non-empty! The values in the from-list don't seem to be validated though; [""]
seems to work just fine, and suddenly the classes show up!
Can anyone explain why this is?
(Standard ubuntu python 2.7.1+ (r271:86832)
Example: to create a dict that maps the names to the classes:
dict([(name, cls) for name, cls in mod.__dict__.items() if isinstance(cls, type)])
where mod is the loaded module
If you define __all__
in the module you are importing, which defines which symbols will be exported, you can iterate by selecting these items specifically.
map(module.__dict__.get, module.__all__)
Method 1:
import inspect
import mymodule
for name, obj in inspect.getmembers(mymodule):
if inspect.isclass(obj):
do stuff...
Method 2:
desired_classes = [obj for name, obj in somemodule.__dict__.items() if isinstance(obj, DesiredType)]
Method 3:
Inside the module you want to iterate on:
File: mymodule.py
class Dog:
VOICE = 'haou'
class Cat:
VOICE = 'meew'
class ImNotIncluded:
VOICE = 'what a shame'
__all__ = ['Dog', 'Cat']
>>> from mymodule import *
>>> Dog.VOICE
'haou'
>>> Cat.VOICE
'meew'
>>> ImNotIncluded.VOICE
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'ImNotIncluded' is not defined
Now to iterate you do:
>>> for cls in map(mymodule.__dict__.get, mymodule.__all__): cls
...
<class 'mymodule.Dog'>
<class 'mymodule.Cat'>
精彩评论