[英]__package__ is None when importing a Python module
I want to import the modules dynamically, by the following way: 我想通过以下方式动态导入模块:
I create a folder named pkg with this structure: 我用这种结构创建了一个名为pkg的文件夹:
pkg
|__init__.py
|foo.py
In the head of __init__.py
, add this code fragement: 在
__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__;
I found m.__package__
is None
in case there is no import statements in foo.py but if I add a simple import statement like this: 我发现如果foo.py中没有import语句,
m.__package__
是None
,但是如果我添加一个这样的简单import语句:
import os
then m.__package__
is "pkg" which is correct package name. 那么
m.__package__
是“pkg”,这是正确的包名。 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. 正如您所注意到的,
__package__
属性未设置一致。 (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. (更多信息在底部。)但是,您应始终能够通过在模块的
__name__
属性中的最后一个句点之前获取所有内容来获取包名称。 Eg. 例如。
mymod.__name__.rpartition('.')[0]
. 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. __package__
属性由导入系统在内部使用,以便在包中轻松进行相对导入。 For details, see PEP 366 . 有关详细信息,请参阅PEP 366 。 To (presumably) save time when loading modules, the attribute is only set if the loaded module imports another module.
为了(可能)在加载模块时节省时间,仅在加载的模块导入另一个模块时才设置该属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.