2009-05-22 4 views
10

Come imposto le importazioni dei moduli in modo che ogni modulo possa accedere agli oggetti di tutti gli altri?Importare correttamente i moduli in Python

Ho un'applicazione Python di medie dimensioni con file di moduli in varie sottodirectory. Ho creato moduli che aggiungono queste sottodirectory a sys.path e importa un gruppo di moduli, utilizzando import thisModule as tm. Gli oggetti del modulo sono indicati con quella qualifica. Quindi importare quel modulo negli altri con from moduleImports import *. Il codice è sciatto in questo momento e ha molte di queste cose, che sono spesso duplicate.

In primo luogo, l'applicazione non funziona perché alcuni riferimenti modulo non sono assegnati. Questo stesso codice viene eseguito quando l'unità viene testata.

In secondo luogo, sono preoccupato di causare problemi con le importazioni di moduli ricorsivi. Importando il moduloImports importa thisModule, che importa moduleImports. . . .

Qual è il modo giusto per farlo?

+0

Non so se questo risponde direttamente alla tua domanda, ma [ho chiesto l'importazione di alcuni giorni fa] (http://stackoverflow.com/questions/860672/lay-out-import-pathing-in-python- straight-e-semplice). Trovato le risposte molto utili. L'importazione circolare –

risposta

21

"Ho un'applicazione Python di medie dimensioni con file di moduli in varie sottodirectory."

Buono. Assicurati che ogni directory includa un file __init__.py, in modo che sia un pacchetto.

"Ho creato moduli che Aggiungi i seguenti sottodirectory di sys.path"

Bad. Utilizzare PYTHONPATH o installare l'intera struttura Lib/site-packages. Non aggiornare sys.path in modo dinamico. È una brutta cosa Difficile da gestire e mantenere.

"importa un gruppo di moduli, utilizzando import thisModule as tm."

Non ha senso. Forse hai uno import thisModule as tm per ogni modulo nella tua struttura. Questa è una pratica standard e tipica: importa solo i moduli che ti servono, nessun altro.

"Ho quindi importare tale modulo in altri con from moduleImports import *"

Bad. Non importare un mucchio di cose a caso.

Ogni modulo dovrebbe avere una lista lunga delle cose specifiche di cui ha bisogno.

import this 
import that 
import package.module 

Elenco esplicito. Nessuna magia Nessuna modifica dinamica a sys.path.

Il mio progetto attuale ha 100 di moduli, una dozzina circa di pacchetti. Ogni modulo importa solo ciò di cui ha bisogno. Nessuna magia

+3

Avvolgere in una frase: "esplicito è meglio di implicito". –

3

Non si otterrà la ricorsione sulle importazioni perché Python memorizza nella cache ogni modulo e non lo ricarica mai.

+1

può davvero accadere ad es. supponiamo b definisce una funzione che un uso ed entrambi importare l'altro vedere http://www.copypastecode.com/codes/view/5193 –

+0

@Anurag Uniyal: hanno effettivamente provato questo? l'importazione tiene traccia di ciò che importa, quindi non c'è garanzia che anche quel codice causerà un caricamento ricorsivo. – SpliFF

+0

accade non ricordo i dettagli esatti ora ma ha qualcosa che fare con lo stesso modulo importato il doppio principale e poi come modulo –

6

alcune indicazioni

  1. si può avere già divisi funzionalità in vari moduli. Se correttamente fatto la maggior parte del tempo si non cadere in importazione circolare problemi (ad esempio, se il modulo dipende un sul b & b in una si può fare un terzo modulo c per rimuovere tale circolare dipendenza). Come ultima risorsa, in un'importazione b ma in b importare a nel punto dove è necessario ad es. all'interno della funzione .

  2. Una volta che la funzionalità è propriamente in gruppo moduli loro in imballaggi che sono in un subdir e aggiungere un file __init__.py ad esso in modo che è possibile importare il pacchetto . Conservare tali documenti in una cartella ad es. lib e poi o aggiungere a sys.path o impostare env PYTHONPATH variabile

  3. from module import * non può essere buona idea. Invece, importa qualsiasi cosa sia necessaria . Potrebbe essere pienamente qualificato. E ' non fa male essere prolisso. per esempio. da pakageA.moduleB import CoolClass.

+0

Minore nota formattazione: Credo che si intende __init__.py (uso backticks intorno ad esso per evitare che di essere convertito in grassetto.) –

+0

grazie, questi semplici linguaggi di formattazione diventa a volte complessa da gestire –

+0

non capisco cosa si intende per "funzionalità split", o come un terzo modulo aiuterebbe a risolvere interdipendenza tra i due moduli. – chernevik

4

Il modo per fare questo è evitare la magia. In altre parole, se il tuo modulo richiede qualcosa da un altro modulo, dovrebbe importarlo esplicitamente. Non dovresti fare affidamento su cose che vengono importate automaticamente.

Come lo Zen di Python (import this) ha, l'esplicito è meglio che implicito.