2011-10-16 2 views
36

In alcuni __init__.py file di moduli ho visto tale linea singola:Cosa significa `__import __ ('pkg_resources'). Declare_namespace (__ nome __)` fare?

__import__('pkg_resources').declare_namespace(__name__) 

cosa fa e perché la gente lo usa? Supponiamo che sia correlato all'importazione dinamica e alla creazione dello spazio dei nomi in fase di runtime.

+1

Potreste trovare questa domanda e risposta utile: http://stackoverflow.com/questions/5064951/packaging-common-python-namespaces –

risposta

34

Si riduce a due cose:

  1. __import__ è una funzione Python che consente di importare un pacchetto utilizzando una stringa come il nome del pacchetto. Restituisce un nuovo oggetto che rappresenta il pacchetto importato. Pertanto, foo = __import__('bar') importerà un pacchetto denominato bar e memorizzerà un riferimento ai suoi oggetti in una variabile di oggetto locale foo.

  2. Dalla configurazione utils documentazione pkg_resources', declare_namespace() "Declare [s] che il nome del nome del pacchetto tratteggiata è un 'pacchetto namespace', il cui contenuto pacchetti ei moduli possono essere distribuiti su più distribuzioni."

Così __import__('pkg_resources').declare_namespace(__name__) importerà il pacchetto 'pkg_resources' in una temporanea e chiamare la funzione declare_namespace memorizzati in quella temporanea (la funzione __import__ è probabile utilizzato piuttosto che l'affermazione import in modo che non ci sia il simbolo aggiuntivo rimasto nome pkg_resources). Se questo codice era my_namespace/__init__.py, __name__ è my_namespace e questo modulo verrà incluso nel pacchetto dello spazio dei nomi my_namespace.

Vedere la documentazione setup tools per maggiori dettagli

Vedere this question per la discussione sul meccanismo più anziani per ottenere lo stesso effetto.

Vedere PEP 420 per il meccanismo standardizzato che fornisce funzionalità simili a partire da Python 3.3.

+0

__import__ è una funzione Python, non è una dichiarazione. –

+0

@PierreThibault Risolto il problema. Grazie! – Nathan

+0

Cosa? No! Questo non è affatto ciò che 'declare_namespace' fa. Non scarica semplicemente il contenuto del modulo 'pkg_resources' nello spazio dei nomi scelto; 'pkg_resources' è solo il modulo da cui proviene' declare_namespace'. Un pacchetto 'pippo' userebbe' pkg_resources.declare_namespace (__ nome __) 'per consentire la sua implementazione da dividere in più cartelle' pippo'. Tirare il contenuto di 'pkg_resources' nel tuo spazio dei nomi sarebbe del tutto controproducente. – user2357112

4

Questo è un modo per dichiarare i cosiddetti "pacchetti namespace" in Python.

Cosa sono e qual è il problema:

Immaginate di distribuire un prodotto software che ha un sacco di funzionalità, e non tutte le persone che vogliono tutto questo, in modo da dividere in pezzi e spedire i plugin come optional .

vuoi che la gente di essere in grado di fare

import your_project.plugins.plugin1 
import your_project.plugins.plugin2 
... 

che va bene se la struttura delle directory è esattamente come sopra, vale a dire

your_project/ 
    __init__.py 
    plugins/ 
     __init__.py 
     plugin1.py 
     plugin2.py 

Ma cosa succede se spedite quei due plugin come python separata pacchetti in modo che si trovino in due diverse directory? Quindi potresti voler inserire __import__('pkg_resources').declare_namespace(__name__) in ogni pacchetto __init__.py in modo che Python sappia che quei pacchetti fanno parte di un "pacchetto spazio dei nomi" più grande, nel nostro caso è your_project.plugins.

Per ulteriori informazioni, fare riferimento allo documentation.

0

Nathan, questa descrizione sembra corretta: "Così __import__('pkg_resources').declare_namespace(__name__) importerà tutti i simboli dal pacchetto pkg_resources e poi aggiungerli a uno spazio dei nomi il cui nome è memorizzato in __name__."

declare_namespace non aggiunge simboli dal pacchetto pkg_resources allo spazio dei nomi il cui nome è memorizzato in __name__.

declare_namespace procede come segue: "Dichiara che il pacchetto 'packageName' è un pacchetto di spazio dei nomi". Riferimento: http://galaxy.readthedocs.io/en/master/lib/pkg_resources.html#pkg_resources.declare_namespace

+0

Sì, io e @ user2357112 abbiamo entrambi ragione. Ho aggiornato la mia risposta per riflettere. – Nathan