python error loading package_导入Python模块时__package__为None

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.py

but 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.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值