2009-04-21 15 views

risposta

121

Un "punto di ingresso" è in genere una funzione (o un altro oggetto funzione richiamabile) che uno sviluppatore o un utente del pacchetto Python potrebbe voler utilizzare, sebbene un oggetto non richiamabile possa essere fornito come un punto di ingresso come bene (come correttamente sottolineato nei commenti!).

Il tipo più comune di punto di ingresso è il punto di ingresso "console_script", che punta a una funzione che si desidera rendere disponibile come strumento da riga di comando a chiunque installi il pacchetto. Questo va nella vostra setup.py come:

entry_points={ 
    'console_scripts': [ 
     'cursive = cursive.tools.cmd:cursive_command', 
    ], 
}, 

Ho un pacchetto che ho appena schierato chiamato "cursive.tools", e ho voluto mettere a disposizione un comando "corsivo" che qualcuno possa eseguire dalla linea di comando, come:

$ cursive --help 
usage: cursive ... 

Il modo per farlo è quello di definire una funzione, come forse una funzione "cursive_command" in corsivo/strumenti/cmd.py che assomiglia:

def cursive_command(): 
    args = sys.argv[1:] 
    if len(args) < 1: 
     print "usage: ..." 

e così via; dovrebbe assumere che sia stato chiamato dalla riga di comando, analizzare gli argomenti che l'utente ha fornito e ... beh, fare ciò che il comando è progettato per fare.

Installare il pacchetto docutils per un ottimo esempio di utilizzo del punto di ingresso: installerà qualcosa come una mezza dozzina di comandi utili per convertire la documentazione di Python in altri formati.

+3

'setup.py' le docutils attuali non contiene' entry_points' a tutti. –

+2

Questa è una risposta eccellente in quanto dimostra la potenza di più progetti che condividono un nome di gruppo entry_point singolo, che è "console_scripts". Confronta questa risposta con la risposta più generale di Petri. Vedrai che setuptools devono utilizzare questo meccanismo pkg_resources per ottenere i console_scripts e quindi creare una shell wrapper intorno a loro. Inspiring? Usa questi. Sono utili per più di semplici console_scripts. –

16

Dal punto di vista astratto, i punti di ingresso vengono utilizzati per creare un registro a livello di sistema di callebles Python che implementano determinate interfacce. Esistono API in pkg_resources per vedere quali punti di ingresso sono pubblicizzati da un determinato pacchetto e API per determinare quali pacchetti pubblicizzano un determinato punto di ingresso.

I punti di ingresso sono utili per consentire a un pacchetto di utilizzare plug-in in un altro pacchetto. Ad esempio, il progetto Paste di Ian Bicking utilizza estesamente i punti di ingresso. In questo caso, è possibile scrivere un pacchetto che pubblicizza la propria produzione dell'applicazione WSGI utilizzando il punto di ingresso paste.app_factory.

Un altro uso per i punti di ingresso è l'enumerazione di tutti i pacchetti sul sistema che forniscono alcune funzionalità di plugin. Il framework web TurboGears utilizza il punto di ingresso python.templating.engines per cercare librerie di modelli installate e disponibili.

152

EntryPoints forniscono una registrazione persistente del nome di oggetto basata su file system e un meccanismo di importazione di oggetti diretti basato sul nome (implementato dal pacchetto setuptools).

Associano nomi di oggetti Python con identificatori a forma libera. Quindi qualsiasi altro codice che utilizza la stessa installazione Python e che conosce l'identificatore può accedere a un oggetto con il nome associato, indipendentemente da dove è definito l'oggetto. I nomi associati possono essere tutti i nomi esistenti in un modulo Python; per esempio nome di una classe, funzione o variabile. Il meccanismo del punto di ingresso non interessa a cosa si riferisce il nome, purché sia ​​impo- nibile.

Come esempio, utilizziamo (il nome di) una funzione e un modulo python immaginario con un nome completo "myns.mypkg.mymodule ':

def the_function(): 
    "function whose name is 'the_function', in 'mymodule' module" 
    print "hello from the_function" 

I punti di ingresso sono registrati tramite una dichiarazione dei punti di ingresso in setup.py. Per registrare the_function sotto entrypoint chiamato 'my_ep_func':

entry_points = { 
     'my_ep_group_id': [ 
      'my_ep_func = myns.mypkg.mymodule:the_function' 
     ] 
    }, 

Come mostra l'esempio, i punti di ingresso sono raggruppati; c'è l'API corrispondente per cercare tutti i punti di ingresso appartenenti ad un gruppo (esempio sotto).

C'era un'installazione del pacchetto (es. Esecuzione 'python setup.py install'), la dichiarazione di cui sopra viene analizzato da setuptools. Quindi scrive le informazioni analizzate in un file speciale. Dopo di che, il pkg_resources API (parte di setuptools) può essere utilizzato per cercare il punto di ingresso e di accedere all'oggetto (s) con il nome associato (s):

import pkg_resources 

named_objects = {} 
for ep in pkg_resources.iter_entry_points(group='my_ep_group_id'): 
    named_objects.update({ep.name: ep.load()}) 

Qui, setuptools leggere le informazioni punto di ingresso che è stato scritto in file speciali. Ha trovato il punto di ingresso, ha importato il modulo (myns.mypkg.mymodule) e recuperato la funzione_funzione definita lì, dopo aver chiamato pkg_resources.load().

Supponendo che non c'erano altre registrazioni punto di ingresso per lo stesso ID gruppo, chiamando the_function sarebbe allora semplice:

>>> named_objects['my_ep_func']() 
hello from the_function 

Così, mentre forse un po 'difficile da afferrare in un primo momento, il meccanismo di punto di ingresso è in realtà abbastanza semplice da usare Fornisce uno strumento utile per lo sviluppo di software Python collegabile.

+4

Dov'è il nome "my_ep_func" usato in tutto questo processo? Non sembra essere usato per niente dall'iteratore pkg_resources. –

+2

@KamilKisiel: nell'esempio qui utilizzato per l'illustrazione, il nome del punto di ingresso non è effettivamente utilizzato per nulla, né è necessario che sia; se il nome del punto di ingresso è utilizzato o meno per qualcosa, dipende dall'applicazione. Il nome è disponibile semplicemente come attributo _name_ dell'istanza del punto di ingresso. – Petri

+1

Penso che scartando l'ep.name e fare named_objects un elenco invece di un dizionario stava confondendo così ho modificato la risposta. Questo è ciò che la risposta mostra sia dove ottenere il nome sia se aspettarsi che sia "the_function" o "my_ep_func". Altrimenti il ​​lettore ha dovuto trovare ulteriore documentazione altrove. Questa è una risposta ECCELLENTE ed è la spiegazione più breve e chiara di entry_point che io abbia mai visto! –

Problemi correlati