__package__ es Ninguno al importar un módulo de Python

Quiero importar los módulos dinámicamente, de la siguiente manera:

Creo una carpeta llamada pkg con esta estructura:

pkg |__init__.py |foo.py 

En la cabecera de __init__.py , agregue este código de código:

 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__; 

Encontré que m.__package__ es None en caso de que no haya declaraciones de importación en foo.py, pero si agrego una statement de importación simple como esta:

 import os 

entonces m.__package__ es “pkg”, que es el nombre correcto del paquete. por que pasa esto

¿Cómo importar un módulo y asegurar su atributo de paquete correcto?

El atributo __package__ , como ha notado, no se establece de manera consistente. (Más información en la parte inferior). Sin embargo, siempre debe poder obtener el nombre del paquete tomando todo antes del último período en el atributo __name__ un módulo. P.ej. mymod.__name__.rpartition('.')[0] . Sin embargo, para su propósito, probablemente sea más fácil simplemente construir la jerarquía de paquetes / módulos a medida que carga los módulos.

Por ejemplo, aquí hay una función que carga todos los módulos dentro de un paquete, cargando recursivamente módulos dentro de subpaquetes, etc. (Supongo que aquí no le importan las funciones con efectos secundarios …)

 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) 

Salida de muestra:

 dummypackage : modx mody pack1 : mod1 pack2 : mod2 

Más información:

El sistema de importación utiliza internamente el atributo __package__ para permitir las importaciones relativas fáciles dentro de un paquete. Para más detalles, ver PEP 366 . Para (probablemente) ahorrar tiempo al cargar módulos, el atributo solo se establece si el módulo cargado importa otro módulo.