问题描述
我想通过以下方式动态导入模块:
我创建了一个名为pkg的文件夹,其结构如下:
pkg
| __init __。py
| foo.py
在 __ init __。py
的头部,添加此代码条纹:
pkgpath = os.path.dirname(pkg .__ file__);
for pkgutil.iter_modules([pkgpath])中的模块:
__import __(module [1],locals(),globals());
m = sys.modules [module [1]];
print m .__ package__;
我发现 m .__包__
是无
如果在foo.py
中没有import语句,但如果我添加了一个简单的import语句:
import os
然后 m .__包__
是pkg,这是正确的包名称。
为什么会发生这种情况?
如何导入模块并确保其正确的包属性?
您注意到的 __ package __
属性未设置一致。 (更多信息在底部。)但是,您应该始终能够通过在模块的 __ name __
属性中的最后一段时间之前获取所有包名称。例如。 mymod .__名__。rpartition(。)[0]
。为了您的目的,在加载模块时,构建软件包/模块层次结构可能更容易。
例如,这里是一个加载所有模块的功能包,递归加载子包中的模块等(我假设你不介意带有副作用的功能..)
import sys
pre>
import pkgutil
from os.path import dirname
def loadModules(pkg):
pkg._modules = []
pkgname = pkg .__ name__
pkgpath = dirname(pkg .__ file__)
for p 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)
如果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
pkg._modules中的m:
如果m._isPackage:
printModules(m,indent)
else:
print' \t'* indent,modName(m)
import dummypackage
loadModules(dummypackage)
printModules(dummypackage)
示例输出:
dummypackage:
modx
mody
pack1:
mod1
pack2:
mod2
更多信息:
导入系统内部使用
__包__
属性方便相关的进口包装。有关详细信息,请参阅。 (大概)在加载模块时节省时间,只有加载的模块导入另一个模块时,属性才会设置。I want to import the modules dynamically, by the following way:
I create a folder named pkg with this structure:
pkg |__init__.py |foo.py
In the head of
__init__.py
, add this code 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__;
I found
m.__package__
isNone
in case there is no import statements in foo.pybut if I add a simple import statement like this:import os
then
m.__package__
is "pkg" which is correct package name.why this happens?How to import a module and ensure its correct package attribute?
解决方案The
__package__
attribute, as you've noticed, isn't set consistently. (More information at the bottom.) However, you should always be able to get the package name by taking everything before the last period in a module's__name__
attribute. Eg.mymod.__name__.rpartition('.')[0]
. For your purpose though, it's probably easier just to build the package/module hierarchy as you load the modules.For example, here's a function that loads all the modules within a package, recursively loading modules within subpackages, etc. (I'm assuming here that you don't mind functions with side-effects..)
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)
Sample output:
dummypackage : modx mody pack1 : mod1 pack2 : mod2
More information:
The
__package__
attribute is used internally by the import system to allow for easy relative imports within a package. For details, see PEP 366. To (presumably) save time when loading modules, the attribute is only set if the loaded module imports another module.这篇关于导入Python模块时__package__为None的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!