use*_*676 8 python load module dynamic
我想通过以下方式动态导入模块:
我用这种结构创建了一个名为pkg的文件夹:
pkg
|__init__.py
|foo.py
Run Code Online (Sandbox Code Playgroud)
在头部__init__.py,添加此代码fragement:
pkgpath = os.path.dirname(pkg.__file__);
for module in pkgutil.iter_modules([pkgpath]):
__import__(module[1], locals(), globals());
m = sys.modules[module[1]];
print m.__package__;
Run Code Online (Sandbox Code Playgroud)
我发现m.__package__是None万一有在foo.py没有import语句,但如果我添加了一个简单的import语句是这样的:
import os
Run Code Online (Sandbox Code Playgroud)
那么m.__package__是"pkg"这是正确的包名.为什么会这样?
如何导入模块并确保其正确的包属性?
__package__正如您所注意到的,该属性未设置一致.(更多信息在底部.)但是,您应该始终能够通过获取模块__name__属性中最后一个句点之前的所有内容来获取包名称.例如.mymod.__name__.rpartition('.')[0].但是,出于您的目的,在加载模块时构建包/模块层次结构可能更容易.
例如,这是一个函数,它加载一个包中的所有模块,递归地加载子包中的模块等(我假设你不介意有副作用的函数..)
import sys
import pkgutil
from os.path import dirname
def loadModules(pkg):
pkg._modules = []
pkgname = pkg.__name__
pkgpath = dirname(pkg.__file__)
for m in pkgutil.iter_modules([pkgpath]):
modulename = pkgname+'.'+m[1]
__import__(modulename, locals(), globals())
module = sys.modules[modulename]
module._package = pkg
# module._packageName = pkgname
pkg._modules.append(module)
if dirname(module.__file__) == pkgpath:
module._isPackage = False
else:
module._isPackage = True
loadModules(module)
def modName(mod):
return mod.__name__.rpartition('.')[-1]
def printModules(pkg, indent=0):
print '\t'*indent, modName(pkg), ':'
indent += 1
for m in pkg._modules:
if m._isPackage:
printModules(m, indent)
else:
print '\t'*indent, modName(m)
import dummypackage
loadModules(dummypackage)
printModules(dummypackage)
Run Code Online (Sandbox Code Playgroud)
样本输出:
dummypackage :
modx
mody
pack1 :
mod1
pack2 :
mod2
Run Code Online (Sandbox Code Playgroud)
更多信息:
该__package__属性由导入系统在内部使用,以便在包中轻松进行相对导入.有关详细信息,请参阅PEP 366.为了(可能)在加载模块时节省时间,仅在加载的模块导入另一个模块时才设置该属性.
| 归档时间: |
|
| 查看次数: |
4727 次 |
| 最近记录: |