2009-07-27 4 views
48

Supponiamo di avere un modulo relativamente lungo, ma ho bisogno di un modulo o metodo esterno solo una volta.Pratica buona o cattiva in Python: importazione nel mezzo di un file

È considerato OK importare quel metodo o modulo nel mezzo del modulo?

Oppure deve essere import solo nella prima parte del modulo.

Esempio:

import string, pythis, pythat 
... 
... 
... 
... 
def func(): 
    blah 
    blah 
    blah 
    from pysomething import foo 
    foo() 
    etc 
    etc 
    etc 
... 
... 
... 

Si prega di giustificare la vostra risposta e aggiungere link al PEP s o fonti pertinenti

+0

Possibile duplicato di [Python - Import se] (http://stackoverflow.com/questions/12860841/python-import-in-if) – Abhijeet

risposta

48

PEP 8 afferma autorevolmente:

Le importazioni sono sempre messo in cima file, subito dopo qualsiasi modulo commenti e docstrings, e prima di variabili globali del modulo e costanti.

PEP 8 dovrebbe essere alla base di qualsiasi stile di guida "in-house", dal momento che riassume ciò che il team di Python nucleo ha trovato ad essere lo stile più efficace, nel complesso (e con il dissenso individuale, naturalmente, come il qualsiasi altra lingua, ma consenso e accordo BDFL su PEP 8).

+1

Alex: è "best practice" ma non sempre evitabile. Vedi l'esempio che ho dato sopra. – jkp

+0

@jkp, S.Lott ha commentato la risposta e ha mostrato perché è evitabile in questo esempio. Gli unici esempi che posso pensare sarebbero usare nomi di moduli generati dinamicamente, quindi '__import__', non semplici import - in * quei * casi che non puoi importare finché non conosci il nome del modulo che stai importando, ma poi non stai usando un semplice 'import' su di esso. –

+0

@ S.Lott "Below" :) – Draemon

7

E 'considerato "buona forma" per raggruppare tutte le importazioni insieme all'inizio del file .

I moduli possono importare altri moduli. È consuetudine ma non è richiesto di posizionare tutte le istruzioni di importazione all'inizio di un modulo (o script, se è per questo). I nomi dei moduli importati sono collocati nella tabella dei simboli globali del modulo di importazione.

Da qui: http://docs.python.org/tutorial/modules.html

8

E 'generalmente considerata una cattiva pratica, ma a volte è inevitabile (ad esempio quando si deve evitare un'importazione circolare).

Un esempio di un momento in cui è necessario: Io uso Waf per creare tutto il nostro codice. Il sistema è suddiviso in strumenti e ogni strumento è implementato nel proprio modulo. Ogni modulo utensile può impiantare un metodo detect() per rilevare se sono presenti i prerequisiti. Un esempio di uno di questi può fare quanto segue:

def detect(self): 
    import foobar 

Se funziona correttamente, lo strumento è utilizzabile. Successivamente, nello stesso modulo, potrebbe essere necessario il modulo foobar, quindi dovrai importarlo di nuovo, a livello di funzione. Chiaramente se fosse importato a livello di modulo le cose sarebbero esplose completamente.

+8

L'importazione all'interno del DEF è certamente evitabile. Usiamo 'try: import x; tranne i blocchi logici di ImportError' per mantenere tutte le importazioni in primo piano. –

+0

Ho particolarmente fatto +1 la parte che riguarda l'importazione circolare, anche se sono d'accordo con tutti gli altri risposta su PEP8. Certo, le importazioni circolari possono e devono essere fissate, ma ciò può rivelarsi inutile.Quindi, nell'interesse di portare valore con il tuo tempo, un'importazione in linea è accettabile se A) le modifiche necessarie per evitare l'importazione in linea sono altamente rischiose per alcuni servizi dal vivo, e | o B) che fissa l'importazione circolare non apporta alcun valore al utente finale (incluso nel lungo periodo re: manutenzione). Forse, anche C) perché ci vuole troppo tempo E ha un valore dubbio. – ThatsAMorais

10

Se il modulo importato viene utilizzato di rado e l'importazione è costosa, l'importazione nel mezzo è OK.

Altrimenti, è consigliabile seguire il suggerimento di Alex Martelli.

2

PEP8:

Le importazioni sono sempre messo in cima file, subito dopo qualsiasi modulo commenti e docstrings, e prima globali modulo e costanti.

Non è una cattiva pratica avere importazioni ritagliate. In modo che l'importazione si applichi solo alla funzione in cui è stata utilizzata.

Penso che il codice sarebbe più leggibile se le importazioni fossero raggruppate nella parte superiore del blocco o se lo si desidera globalmente nella parte superiore del file.

2

Beh, penso che sia una buona pratica di raggruppare tutte le importazioni insieme all'inizio del file dopo tutti sanno dove cercare, se volete sapere quali librerie vengono caricati

15

C'è stata una discussione dettagliata di questo argomento sul mailing list Python nel 2001:

https://mail.python.org/pipermail/python-list/2001-July/071567.html

+3

Upvoting di questo per fornire un collegamento a una discussione, piuttosto che solo "afferma PEP 8" così". Direi che la "carne" di esso inizia diversi messaggi nel thread (http://mail.python.org/pipermail/python-list/2001-July/097866.html). –

+5

I collegamenti sopra sono morti, ma questo sembra funzionare: https://mail.python.org/pipermail/python-list/2001-July/071567.html Alcune delle discussioni potrebbero essere cancellate. – jtpereyda

+2

Questa è una risposta di solo collegamento e non è utile. Metti invece la carne della tua risposta qui. – Jess

6

95% del tempo, si dovrebbe mettere tutti i tuoi importazioni nella parte superiore del file. Un caso in cui si potrebbe voler eseguire un'importazione locale della funzione è se si deve farlo per evitare importazioni circolari. Dì foo.py importa bar.py, e una funzione in bar.py ha bisogno di importare qualcosa da foo.py. Se imposti tutte le tue importazioni nella parte superiore, potresti avere problemi imprevisti nell'importazione di file che si basano su informazioni che non sono ancora state compilate. In questo caso, con un import locale funzione può consentire il codice per tenere a bada sull'importazione l'altro modulo fino a quando il suo codice è stato completamente compilato, e si chiama la funzione in questione.

Tuttavia, sembra che il tuo caso d'uso è di più che lo rende chiaro dove foo() è venuta da. In questo caso, avrei di gran lunga preferire una delle due cose:

In primo luogo, piuttosto che

from prerequisite import foo 

importazione prerequisito direttamente, e in seguito si riferiscono ad essa come prerequisite.foo. La verbosità aggiunta si ripaga di picche grazie a una maggiore trasparenza del codice.

In alternativa, (o in combinazione con quanto sopra) se è davvero una distanza così lunga tra l'importazione e il luogo di utilizzo, è possibile che il modulo sia troppo grande. La necessità di un'importazione che nient'altro utilizza potrebbe essere un'indicazione di un luogo in cui il tuo codice potrebbe essere riadattato in un frammento di dimensioni più maneggevoli.

+3

La circolarità può essere risolta con la scomposizione. Le importazioni condizionali sono - nel migliore dei casi - una grossa soluzione. Direi che è il 99,7% delle volte e lo 0,3% è "finché non decomponi per correggere la circolarità". –

14

Tutti gli altri hanno già menzionato i PEP, ma si prendono anche cura di non avere istruzioni di importazione nel mezzo del codice critico. Almeno in Python 2.6, ci sono molte altre istruzioni bytecode richieste quando una funzione ha un'istruzione import.

>>> def f(): 
    from time import time 
    print time() 

>>> dis.dis(f) 
    2   0 LOAD_CONST    1 (-1) 
       3 LOAD_CONST    2 (('time',)) 
       6 IMPORT_NAME    0 (time) 
       9 IMPORT_FROM    0 (time) 
      12 STORE_FAST    0 (time) 
      15 POP_TOP    

    3   16 LOAD_FAST    0 (time) 
      19 CALL_FUNCTION   0 
      22 PRINT_ITEM   
      23 PRINT_NEWLINE  
      24 LOAD_CONST    0 (None) 
      27 RETURN_VALUE 

>>> def g(): 
    print time() 

>>> dis.dis(g) 
    2   0 LOAD_GLOBAL    0 (time) 
       3 CALL_FUNCTION   0 
       6 PRINT_ITEM   
       7 PRINT_NEWLINE  
       8 LOAD_CONST    0 (None) 
      11 RETURN_VALUE 
Problemi correlati