2011-12-17 12 views
5

Me pregunto por qué el directorio (subpaquete) que contiene submódulos en un paquete python aparece como un símbolo cuando se importa el paquete. Por ejemplo, si tengo este paquete:paquete de importación python - subpaquete no debería aparecer en la tabla de símbolos

PyModTest/      Top-level package 
      __init__.py    Initialize the package 
      Source/     Subpackage holding source files 
       __init__.py 
       WildMod.py  Submodule containing a function: 'WildFunc' 

donde el __init__.py nivel superior se parece a esto:

#!/usr/bin/env python 

from Source.WildMod import WildFunc 

y, por el amor integridad, el __init__.py nivel inferior tiene este aspecto :

#!/usr/bin/env python 

__all__ = ["WildMod"] 

OK, por lo que ahora abro el intérprete, importar el módulo, y mirar los símbolos:

>>> import PyModTest 
>>> dir(PyModTest) 
['Source', 'WildFunc', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__'] 

SEE, aparece el módulo 'Fuente', ¡aunque nunca lo importé específicamente!

El único símbolo (además de los privados) que quiero ver es mi 'WildFunc'. ¿Hay alguna forma de ocultar el paquete 'Fuente'?

Respuesta

6

Dos cosas a tener en cuenta aquí:

  • En Python, los módulos son objetos reales, y el punto que aparece entre sus nombres representa un acceso atributo real
  • Usted está haciendo una importación relativo, lo que significa que Source es en realidad PyModTest.Source (gracias a TokenMacGuy por señalar esto)

por lo tanto: con el fin de importar PyModTest.Source.WildMod.WildFunc, que Python

  1. importación PyModTest (que ya se ha hecho por usted)
  2. cheque y ver si tiene un atributo llamado Source, y si no es así, crear el atributo mediante la importación de PyModTest/Source/__init__.py
  3. comprobar y ver si eso tiene un atributo llamado WildMod, y si no es así, crear el atributo mediante su importación desde PyModTest/Source/WildMod.py
  4. comprobar y ver si eso tiene un atributo llamado WildFunc (que lo hace)

Algunos detalles relevantes se discuten en PEP 302 y en Python language reference.

Más abajo en el mecanismo, una importación de nombre punteado se divide por sus componentes. Para "import spam.ham", primero un "import spam" es hecho, y solo cuando eso sucede es "ham" importado como un submódulo de "spam".

Si no quiere tener una variable llamada Source, eso es fácil de arreglar: sólo del Source después de importar la función. Pero tenga en cuenta que evitará que cualquier código que se ejecute más adelante acceda al PyModTest.Source.<anything> (excepto para WildFunc, ya que ha guardado una referencia a eso).Definitivamente, sugeriría ignorar la referencia al Source, no borrarla, ya que no está dañando nada.

+0

Impresionante, eso tiene sentido. Gracias por la sugerencia sobre 'del Source' :) – rokuingh

+2

'Source' es un subpaquete de' PyModTest', la importación implícita se transforma silenciosamente en 'from PyModTest.Source import ...', y entonces el módulo 'Source' debe se agregará como un atributo del módulo 'PyModTest'. Si se ha encontrado 'Source' fuera del paquete' PyModTest' (improbable, los subpaquetes tienen prioridad sobre 'sys.path'), esto no habría ocurrido. Para evitar confundirse a usted mismo y a los demás, siempre prefiera las importaciones absolutas. – SingleNegationElimination

+0

@TokenMacGuy: ah, buena captura. De alguna manera me perdí el hecho de que esto era una importación relativa. –

Cuestiones relacionadas