2009-12-24 7 views
17

Importación del módulo estándar "registro" contamina sys.modules con un montón de entradas ficticias:¿Por qué hay módulos ficticios en sys.modules?

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 

Así importar este paquete pone nombres adicionales en sys.modules, excepto que no son módulos, sólo las referencias a Ninguno . Otros módulos (por ejemplo, xml.dom y codificaciones) tienen este problema también. ¿Por qué?

Editar: Sobre la base de la respuesta de bobince, hay páginas que describen the origin (véase la sección "Entradas de maniquí en sys.modules") y future de la función.

+0

Buen enlace ... En realidad no había visto esto documentado en ninguna parte antes. Evidentemente, por alguna razón, no había buscado el título obvio "The Knights Who Say Neeeow ... Wum ... Ping". Ah, Python ... – bobince

+1

Iba a publicar un duplicado exacto - mi segundo hoy: P –

Respuesta

23

None valores en sys.modules son fallas en caché de búsquedas relativas.

Así que cuando estás en el paquete foo y 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 verificar el sistema de archivos para foo/sys.py nuevamente en importaciones relativas adicionales, almacena None en el sys.modules para indicar que el módulo no existe y que una importación posterior no debe volver a aparecer allí, sino que debe ir directamente al sys cargado.

Este es un detalle de implementación de cPython en el que no puede confiar, pero tendrá que saberlo si está realizando hacks de importación/recarga desagradables.

Pasa a todos los paquetes, no solo a logging. Por ejemplo, import xml.dom y vea xml.dom.xml en la lista de módulos mientras intenta importar xml desde adentro de xml.dom.

Como Python avanza hacia la importación absoluta, esta fealdad ocurrirá menos.

+0

¡Gracias! Agregué enlaces en mi pregunta al fondo y a los que se hace referencia en http://www.python.org/dev/peps/pep-0328 –

+0

. Si "le sucede a todos los paquetes", ¿por qué nunca he visto esto con los míos? ¿cosas? Esperaría ver "mymodule.sys", "mymodule.os" y demás con docenas y docenas de tales módulos ficticios pero solo verlo con algunos como xml.dom, logging y codificaciones (como D.Shawley menciones). –

+0

Sucede a mis paquetes. Pero solo paquetes, no simples módulos. – bobince

0

No estoy seguro de por qué sucede, pero encodings muestra 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é lo que está pasando con algunas de las entradas siendo None pero puedo decir que no es única para el módulo logging.

Cuestiones relacionadas