2015-01-30 2 views
20

Ho notato che Flask stava usando Werkzeug su __import__ un modulo, ed ero un po 'confuso. Sono andato a controllare i documenti su di esso e ho visto che sembra darti più controllo in qualche modo in termini di dove cerca il modulo, ma non sono sicuro esattamente come e non ho idea di come sia diverso da importlib.import_module .import vs __import __() vs importlib.import_module()?

La cosa strana nell'esempio Werkzeug è che si dice solo __import__(import_name), quindi non vedo come questo è diverso da solo utilizzando l'istruzione import, dal momento che è ignorare i parametri extra opzionali.

Qualcuno può spiegare? Ho esaminato altre persone che avevano già fatto domande simili su SO in precedenza, ma non erano domande formulate in modo molto chiaro e le risposte non lo avevano affatto risolto.

+1

Usa '' __import__' dove si desidera importare un modulo il cui nome è conosciuto solo a runtime'. Diverso da questo...come hai detto, questo ti dà più potenza rispetto all'importazione. –

+0

Se la memoria funziona correttamente, c'è un video di David Beasly durante l'importazione, nel video menziona che WerkZeug ha sovraccaricato l'importazione per qualche motivo. – Carel

risposta

34

__import__ è una funzione di hook di basso livello che viene utilizzata per importare i moduli; può essere usato per importare un modulo dinamicamente dando il nome del modulo da importare come variabile, qualcosa che la dichiarazione import non ti permetterà di fare.

importlib.import_module() è un involucro attorno al gancio * per produrre una API piacevole per la funzionalità; è un'aggiunta molto recente a Python 2, ed è stata più sviluppata in Python 3. I codebase che usano __import__ generalmente lo fanno perché vogliono rimanere compatibili con le versioni precedenti di Python 2, ad es. qualsiasi cosa prima di Python 2.7.

Un effetto collaterale dell'utilizzo di __import__ può essere che restituisce il modulo importato e non aggiunge nulla allo spazio dei nomi; puoi importare con esso senza dover poi cancellare il nuovo nome se non volevi quel nuovo nome; utilizzando import somename si aggiungerà somename al proprio spazio dei nomi, ma invece __import__('somename') restituisce il modulo importato, che è possibile quindi ignorare. Werkzeug usa il gancio per questo motivo in un'unica posizione.

Tutti gli altri usi hanno a che fare con le importazioni dinamiche. Werkzeug supporta Python 2.6, quindi non può usare importlib.


*importlib è un'implementazione Pure-Python e import_module() utilizzerà tale attuazione, whist __import__ userà una versione C-ottimizzata. Entrambe le versioni richiamano allo importlib._bootstrap._find_and_load() quindi la differenza è per lo più accademica.

+0

Non capisco cosa intendi con "puoi importare con esso senza dover poi cancellare il nuovo nome se non volevi che il nuovo nome". Se hai un minuto potresti forse incarnarlo come se parlassi con un bambino piccolo? – Aerovistae

+0

@Aerovistae: aggiornato un po '; 'import sys' aggiunge il nome' sys' al tuo spazio dei nomi (associato al modulo), '__import __ ('sys')' restituisce l'oggetto modulo 'sys' al chiamante, che è quindi libero di ignorare quell'oggetto. –

+0

@MartijnPieters Per namespace intendi 'sys.modules'? – NeoWang

3

__import__(import_name), quindi non vedo come questo è diverso da usando solo l'istruzione import

Sia __import__() e importlib.import_module() consentono di importare un modulo quando si ha il modulo nome come una stringa. Non si può scrivere:

x = 're' 
import x 

o avrai:

File "1.py", line 3, in <module> 
import x ImportError: No module named x