2012-01-27 1 views
6

In caso di dubbio, di solito inserisco le mie istruzioni di importazione nella parte superiore del modulo. Spesso, questo riduce la ripetizione, che è bello. C'è un lato negativo delle prestazioni, tuttavia, nel caso in cui solo una singola funzione (o classe) richiede l'importazione?Importazione Python a livello di funzione VS. Livello modulo

importa quanto segue quando viene richiamata la funzione?

 def func(): 
     from task import test 

Se è così, immagino che potrebbe essere una leggera efficienza. Suppongo anche che si possano ottenere alcuni punti aggiunti per una raccolta dei dati più veloce e un ambito variabile, poiché gli oggetti importati non verrebbero aggiunti al dizionario globale. Come un altro poster gentilmente messo:

Ciò è dovuto principalmente alla ricerca variabile. La ricerca di una variabile nell'ambito globale richiede una ricerca nel dizionario. Al contrario, il compilatore determina staticamente i nomi locali e li fa riferimento per indice, quindi non è richiesta la ricerca del dizionario.

Queste ipotesi corrette sono totalmente fuori base?

Grazie

+2

Come per le prestazioni di ricerca del nome: ** Non importa. ** Nel raro caso in cui lo fai, scoprirai quando avrai finito il codice, scoperto che è troppo lento e profilato. – delnan

risposta

4

Un'importazione in una funzione viene importata solo quando viene eseguita la funzione. Tieni presente che in Python tutte le istruzioni vengono eseguite quando vengono rilevate e le importazioni sono istruzioni come qualsiasi altra cosa. Le importazioni di livello superiore vengono importate quando il modulo viene importato, poiché sono istruzioni di livello superiore nel modulo.

Le vostre preoccupazioni sulla ricerca del nome sono sbagliate: la differenza è trascurabile e deve essere presa in considerazione solo se la profilazione mostra un problema.

I moduli vengono importati nello scope della funzione solo per due motivi: 1) per risolvere problemi di importazione circolare, che potrebbero essere risolti in altri modi mediante il refactoring oppure 2) se il modulo è facoltativo e la funzione non è usato da molti dei miei utenti. Nel caso di 2), il modulo può essere completamente mancante e non ci sarà alcun problema a meno che qualcuno non invochi la funzione.

+0

Questa era più di una domanda teorica. Sembra che ci sia una differenza, anche se trascurabile. Grazie Ned – Ben

+0

È quello il modo più poderoso? Vedo che alcune persone fanno importazioni in __init__.py nella radice del loro modulo e importano tutto da lì. Può essere usato per risolvere determinate importazioni circolari? – radtek

3

consente di guardare a ciò che il bytecode sarebbe simile per le seguenti due funzioni:

def func1(): 
    """ test imported each time function is run """ 
    from task import test 
    test() 

def func2(): 
    """ test was imported at top of module """ 
    test() 

Come potete vedere qui sotto, func2() fa risparmiare un sacco di passi utilizzando la funzione di importazione a livello globale test .

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

    4   16 LOAD_FAST    0 (test) 
      19 CALL_FUNCTION   0 
      22 POP_TOP 
      23 LOAD_CONST    3 (None) 
      26 RETURN_VALUE 
>>> dis.dis(func2) 
    3   0 LOAD_GLOBAL    0 (test) 
       3 CALL_FUNCTION   0 
       6 POP_TOP 
       7 LOAD_CONST    1 (None) 
      10 RETURN_VALUE 

Prendere questo in considerazione è probabilmente l'ottimizzazione prematura, come sottolineato nel commento di delnan.

Per quanto riguarda lo standard test nello spazio dei nomi globale, è improbabile che causi problemi di prestazioni di ricerca. Il modo più notevole che penso si possa vedere è se ci fosse una collisione hash per test e un altro nome che si usa molto spesso, il che ha richiesto più tempo per la ricerca di questo secondo nome. Ancora una volta, l'ottimizzazione prematura di considerare quel caso raro in anticipo.

+1

Ma nota che in realtà non importerà il modulo più di una volta, ma semplicemente controlla se è necessario ogni volta che viene chiamato. – delnan

+0

Grazie per averlo esposto così; è utile Non avevo familiarità con la dis library. – Ben

0

Penso che abbia senso inserire l'importazione nella definizione se non verrà chiamata molto spesso.