2011-12-17 19 views
5

Mi chiedo perché la directory (subpackage) che contiene i sottomoduli in un pacchetto python si presenta come un simbolo quando il pacchetto viene importato. Per esempio, se ho questo pacchetto:pacchetto di importazione python - il pacchetto secondario non deve essere visualizzato nella tabella dei simboli

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

dove il __init__.py livello superiore assomiglia a questo:

#!/usr/bin/env python 

from Source.WildMod import WildFunc 

e, per completezza, il livello più basso __init__.py si presenta così :

#!/usr/bin/env python 

__all__ = ["WildMod"] 

OK, ora apro l'interprete, importare il modulo, e guardare i simboli:

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

VEDERE, il modulo 'Origine' si presenta, anche se non l'ho mai importato in modo specifico!

L'unico simbolo (oltre a quelli privati) che voglio vedere è il mio 'WildFunc'. C'è un modo per nascondere il pacchetto 'Source'?

risposta

6

Due cose da notare qui:

  • In Python, i moduli sono oggetti reali, e il punto che appare tra i loro nomi rappresenta un effettivo accesso attributo
  • State facendo un import relativo, nel senso che Source è in realtà PyModTest.Source (grazie a TokenMacGuy per la precisazione)

Quindi: per importare PyModTest.Source.WildMod.WildFunc, Python deve

  1. importazione PyModTest (che era già stato fatto da voi)
  2. controllo e vedere se ha un attributo chiamato Source, e se non, creare l'attributo mediante l'importazione da PyModTest/Source/__init__.py
  3. controllare e vedere se che ha un attributo chiamato WildMod, e se non, crea l'attributo importandolo da PyModTest/Source/WildMod.py
  4. controllo e vedere se ha un attributo denominato WildFunc (che fa)

Alcuni dettagli rilevanti sono discussi in PEP 302 e nello Python language reference.

Più giù nel meccanismo, un nome punteggiato l'importazione viene suddivisa da i suoi componenti. Per "", prima un "import spam" è terminato e solo quando questo succede è "ham" importato come sottomodulo di "spam".

Se non si desidera avere una variabile denominata Source, che è facile da risolvere: basta del Source dopo aver importato la funzione. Tuttavia, tieni presente che impedirà l'accesso a qualsiasi codice eseguito successivamente a PyModTest.Source.<anything> (ad eccezione di WildFunc, dal momento che hai salvato un riferimento).Suggerisco senz'altro di ignorare il riferimento a Source, non cancellandolo, poiché non danneggia nulla.

+0

Impressionante, questo ha senso. Grazie per il suggerimento sul 'del Source' :) – rokuingh

+2

'Source' è un sotto pacchetto di' PyModTest', l'importazione implicita viene automaticamente trasformata in 'da PyModTest.Source import ...', e quindi il modulo 'Source' deve essere aggiunto come attributo del modulo 'PyModTest'. Se 'Source' è stato trovato all'esterno del pacchetto' PyModTest' (improbabile, i subpackages hanno la precedenza su 'sys.path'), questo non si sarebbe verificato. Per evitare di confondere te stesso e gli altri, preferisci sempre le importazioni assolute. – SingleNegationElimination

+0

@TokenMacGuy: ah, buona cattura. In qualche modo ho perso il fatto che si trattava di un'importazione relativa. –

Problemi correlati