python - imports - ¿Por qué hay módulos ficticios en sys.modules?
python import subdirectory (2)
No estoy seguro de por qué sucede, pero las encodings
exhiben las mismas referencias a None
.
Python 2.6.2 (r262:71600, May 24 2009, 00:12:54)
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> for n in filter(lambda x: x.startswith(''encodings''), sys.modules):
... print n, type(sys.modules[n])
...
encodings <type ''module''>
encodings.encodings <type ''NoneType''>
encodings.codecs <type ''NoneType''>
encodings.__builtin__ <type ''NoneType''>
encodings.utf_8 <type ''module''>
encodings.aliases <type ''module''>
Realmente no sé qué sucede con algunas de las entradas que son None
pero puedo decir que no es exclusivo del módulo de logging
.
La importación del módulo estándar de "registro" contamina sys.modules con un montón de entradas ficticias:
Python 2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel)] on win32
>>> import sys
>>> import logging
>>> sorted(x for x in sys.modules.keys() if ''log'' in x)
[''logging'', ''logging.atexit'', ''logging.cStringIO'', ''logging.codecs'',
''logging.os'', ''logging.string'', ''logging.sys'', ''logging.thread'',
''logging.threading'', ''logging.time'', ''logging.traceback'', ''logging.types'']
# and perhaps even more surprising:
>>> import traceback
>>> traceback is sys.modules[''logging.traceback'']
False
>>> sys.modules[''logging.traceback''] is None
True
Por lo tanto, la importación de este paquete incluye nombres adicionales en sys.modules, excepto que no son módulos, solo hacen referencia a Ninguno. Otros módulos (por ejemplo, xml.dom y codificaciones) también tienen este problema. ¿Por qué?
Edición: basándose en la respuesta de Bobince, hay páginas que describen el origen (consulte la sección "Entradas ficticias en sys.modules") y el future de la función.
None
valores en sys.modules
son fallas en caché de búsquedas relativas.
Entonces, cuando estás en el paquete foo
e import sys
, Python busca primero un módulo foo.sys
, y si eso falla, va al módulo de nivel superior sys
. Para evitar tener que revisar el sistema de archivos para foo/sys.py
nuevamente en futuras importaciones relativas, almacena None
en los sys.modules
para sys.modules
que el módulo no existía y que una importación posterior no debería mirar allí nuevamente, sino que sigue recto a los sys
cargados.
Este es un detalle de implementación de cPython en el que no puedes confiar, pero deberás saberlo si estás realizando un desagradable pirateo de importación / recarga mágica.
Le sucede a todos los paquetes, no solo al logging
. Por ejemplo, import xml.dom
y vea xml.dom.xml
en la lista de módulos mientras intenta importar xml
desde xml.dom
.
A medida que Python avanza hacia la importación absoluta, esta fealdad sucederá menos.