本文介绍了导入Python模块时__package__为None的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过以下方式动态导入模块:



我创建了一个名为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 
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)
pre>

示例输出:

  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__ is None 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 11:22