导入Python模块时__package__为None

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"这是正确的包名.为什么会这样?

如何导入模块并确保其正确的包属性?

sb.*_*sb. 9

__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.为了(可能)在加载模块时节省时间,仅在加载的模块导入另一个模块时才设置该属性.