遍历动态导入模块中的类
我有一个来自子包的模块是动态导入的;我该如何遍历它里面的类呢?
我一直在这样导入模块并列出名称:
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)"%package
module = __import__(package) # this succeeds
for name,obj in inspect.getmembers(module):
print name,type(obj)
这样做只会打印模块的属性,而不会显示模块定义的类类型:
__builtins__ <type 'dict'>
__doc__ <type 'NoneType'>
__file__ <type 'str'>
__name__ <type 'str'>
__package__ <type 'NoneType'>
__path__ <type 'list'>
imported_package <type 'module'>
看起来我的类不在 __dict__
里面,除非 fromlist
不是空的!不过,从列表里的值似乎并没有被验证;像 [""]
这样的值也能正常工作,结果类就突然出现了!
有人能解释一下这是为什么吗?
(标准的ubuntu python 2.7.1+ (r271:86832))
3 个回答
4
方法一:
import inspect
import mymodule
for name, obj in inspect.getmembers(mymodule):
if inspect.isclass(obj):
do stuff...
方法二:
desired_classes = [obj for name, obj in somemodule.__dict__.items() if isinstance(obj, DesiredType)]
方法三:
在你想要循环的模块里面:
文件: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
现在要进行循环,你可以这样做:
>>> for cls in map(mymodule.__dict__.get, mymodule.__all__): cls
...
<class 'mymodule.Dog'>
<class 'mymodule.Cat'>
6
如果你在要导入的模块里定义了 __all__
,这个定义会告诉程序哪些内容可以被导出。这样的话,你就可以专门选择这些内容来进行遍历。
map(module.__dict__.get, module.__all__)
57
举个例子:我们可以创建一个字典,用来把名字和类对应起来:
dict([(name, cls) for name, cls in mod.__dict__.items() if isinstance(cls, type)])
这里的 mod 是已经加载的模块。