Esperienza di "PEP-302 New Import Hooks" di Python [chiuso]


41

Sono uno degli sviluppatori di Ruby (CRuby). Stiamo lavorando alla versione 2.0 di Ruby (prevista per il 2012 / febbraio).

Python ha "PEP302: New Import Hooks" (2003):

Questo PEP propone di aggiungere un nuovo set di hook di importazione che offrono una migliore personalizzazione del meccanismo di importazione di Python. Contrariamente all'attuale hook di importazione , un hook di nuovo stile può essere iniettato nello schema esistente, consentendo un controllo più fine di come vengono trovati i moduli e come vengono caricati.

Stiamo considerando di introdurre una funzionalità simile a PEP302 in Ruby 2.0 (CRuby 2.0). Voglio fare una proposta che possa convincere Matz. Attualmente, CRuby può caricare gli script solo dai file system in modo standard.

Se hai qualche esperienza o considerazione su PEP 302, ti preghiamo di condividere.

Esempio:

  1. È una grande specifica. Non c'è bisogno di cambiarlo.
  2. È quasi buono, ma ha questo problema ...
  3. Se potessi tornare al 2003, allora cambierei le specifiche in ...

6
Wow, il ragazzo YARV stesso, ciao e benvenuto ai programmatori! ;) Su Stack Exchange non ci piace molto la discussione aperta, ci piace invece risolvere problemi specifici (dai una rapida lettura alle nostre FAQ ) - che suppongo sia il motivo per cui la tua domanda è stata chiusa su Stack Overflow e ha già un voto stretto qui. Dovresti provare a renderlo un po 'più specifico - hai una preoccupazione specifica per PEP 302 che ha motivato questa domanda?
yannis,

4
Grazie per il tuo commento, Yannis. Penso di voler discutere di "architettura software". PEP302 sembra un framework potente e generale per estendere i propri caricatori su interprete Python. Tuttavia, potenti funzionalità presentano rischi come un uso eccessivo (genera codici magici), impedendo l'ottimizzazione dell'interprete. Quindi voglio sapere che questo framework di estensioni è dolce o no per gli utenti di Python e gli sviluppatori di interpreti. Credo che studiare la storia mi aiuterà a fare buone specifiche su Ruby 2.0.
Koichi Sasada,

Grazie modificando la mia domanda piuttosto. E mi dispiace se questa domanda non è preferibile.
Koichi Sasada,

Questo è un fantastico esempio di come una domanda che sembra fallire il nostro test "sondaggio d'opinione", può comunque dimostrare di avere un valore sorprendente.
Ross Patterson,

Risposte:


47

Sono il manutentore del modulo runpy di Python e uno dei manutentori dell'attuale sistema di importazione. Mentre il nostro sistema di importazione è incredibilmente flessibile, sconsiglio di adottarlo all'ingrosso senza apportare alcune modifiche: a causa di problemi di compatibilità con le versioni precedenti, ci sono un sacco di cose che sono più imbarazzanti di quanto altrimenti dovrebbero essere.

Una cosa che ha danneggiato PEP 302 in Python è quanto tempo ci è voluto per convertire il sistema di importazione di base in usarlo. Per la parte migliore di un decennio, chiunque abbia fatto qualcosa di complesso con gli hook di importazione è stato bloccato implementando due pezzi: uno che gestiva caricatori conformi a PEP 302 (come le importazioni zip) e un secondo che gestiva il meccanismo di importazione basato su filesystem standard. Solo nella prossima 3.3 la gestione dei caricatori PEP 302 si occuperà anche della gestione dei moduli importati attraverso il meccanismo standard di importazione del filesystem. Cerca di non ripetere quell'errore se puoi evitarlo.

PEP 420 (implementato per Python 3.3) aggiunge alcune modifiche al protocollo per consentire agli importatori di contribuire con porzioni ai pacchetti dello spazio dei nomi. Risolve anche un problema di denominazione nella definizione dell'API del Finder (sostituendo efficacemente l'errato "find_module" con il più preciso "find_loader"). Si spera che tutto ciò dovrebbe essere documentato più chiaramente nelle specifiche della lingua entro il tempo 3.3rc1 in giro tra un paio di settimane.

Un altro problema notevole è che l'approccio documentato in modo specifico in PEP 302 ha troppi processi globali. Non seguirci lungo questo percorso: prova a incapsulare lo stato in un modello a oggetti più coerente, quindi è leggermente più semplice importare selettivamente altri moduli (i moduli di estensione C sono la rovina di rendere tale incapsulamento completamente efficace, ma anche un certo livello di incapsulamento può essere utile).

PEP 406 (http://www.python.org/dev/peps/pep-0406/) discute una possibile evoluzione retrocompatibile dell'approccio di Python con una migliore incapsulamento dello stato. Tuttavia, se si dispone di un modello di stato incapsulato dall'inizio, è possibile definire le API di conseguenza ed evitare che importatori e caricatori accedano allo stato globale (anziché passare un riferimento al motore attivo).

Un altro pezzo mancante in PEP 302 è la possibilità di chiedere a un importatore un iteratore sui moduli forniti da quell'importatore (questo è necessario per cose come le utilità di congelamento e le utilità di documentazione automatica che estraggono docstring). Dal momento che è incredibilmente utile, probabilmente sarebbe meglio standardizzarlo fin dall'inizio : http://docs.python.org/dev/library/pkgutil#pkgutil.iter_modules (probabilmente lo eleveremo infine a un valore formalmente specificato API in Python 3.4)

E il mio ultimo commento è che dovresti dare un'occhiata da vicino alla divisione delle responsabilità tra il sistema di importazione e gli oggetti del caricatore. In particolare, prendere in considerazione la suddivisione dell'API "load_module" in passaggi separati "init_module" ed "exec_module". Ciò dovrebbe consentire di ridurre al minimo il grado in cui i caricatori devono interagire direttamente con lo stato di importazione.

PEP 302 e importlib sono un ottimo punto di partenza per un sistema di importazione più flessibile, ma ci sono sicuramente errori che vale la pena evitare.


1
Non sono ancora del tutto finiti, ma una bozza iniziale dei documenti di sistema di importazione completi è disponibile su docs.python.org/dev/reference/import
ncoghlan,

1
python.org/dev/peps/pep-0451 è un aggiornamento del sistema di importazione di Python per Python 3.4 che affronta molti dei commenti di Brett e I qui.
ncoghlan,

28

Accanto a ncoghlan sono l'altro manutentore del sistema di importazione di Python e l'autore della sua attuale implementazione, importlib (http://docs.python.org/dev/py3k/library/importlib.html). Tutto ciò che Nick ha detto sono d'accordo, quindi voglio solo aggiungere alcune informazioni extra.

Innanzitutto, non fare troppo affidamento su PEP 302 direttamente, ma guarda invece cosa fornisce importlib in termini di classi di base astratte, ecc. Per la retrocompatibilità le cose dovevano essere compatibili con PEP 302, ma ho dovuto aggiungere alcune delle mie proprie API al fine di completare il supporto per una vera flessibilità.

Un altro punto importante è che stai dando agli sviluppatori due flessibilità. Uno è la possibilità di archiviare il codice in un modo diverso dal solo direttamente sul file system come singoli file (io chiamo questo back-end di archiviazione per le importazioni), ad esempio questo consente al codice di vivere in un file zip, database sqlite, ecc. L'altro supporto è nel consentire il controllo del codice pre o post-elaborazione in qualche modo, ad esempio Chisciotte (https://www.mems-exchange.org/software/quixote/) e il suo uso alternativo di letterali stringa non assegnati a una variabile sarebbe molto più semplice da supportare.

Mentre il secondo è raramente necessario, il primo è dove devi preoccuparti del supporto. Ed è qui che finisci per ridefinire praticamente le API di interazione del file system. Poiché alcune persone hanno bisogno di risorse archiviate come file con il loro codice, è necessario fornire un buon modo per leggere file, scoprire file, ecc. Dobbiamo ancora implementare la parte dell'API per scoprire quali file di dati sono disponibili, elencarli, ecc. .

Ma poi hai anche la necessità di API che siano specifiche del codice. Come accennato da Nick, alla fine hai bisogno di API per scoprire quali moduli contiene un pacchetto, ecc. Che non sono specifici del file. C'è questa strana dualità di avere API per gestire i moduli in cui hai estratto il concetto di file, ma alla fine hai bisogno di fornire API per accedere a dati di risorse simili a file. E non appena si tenta di implementare l'uno rispetto all'altro per evitare la duplicazione, le acque diventano davvero torbide (cioè le persone finiscono per fare affidamento sulla strutturazione del percorso del file prevista, ecc. Senza prestare attenzione al fatto che il percorso potrebbe non essere un vero percorso perché è per un file zip contenente codice e non solo un file). IOW finirai per dover implementare due API simili, ma a lungo andare starai meglio.

Come ha detto Nick, la nostra soluzione è un buon punto di partenza, ma non è come lo farei oggi se stessi progettando l'API da zero.


-1

PEP 302 ti consente di collegarti al meccanismo di importazione di Python, il che significa che puoi importare codice da altre fonti come database, file zip e così via.

Nell'implementazione Python delle importazioni c'è una lunga storia di complessità che sarà presto semplificata dall'introduzione di un'implementazione Python delle importazioni.

Dovrei consigliare di pensare a lungo e duramente ai casi d'angolo. Quindi è probabile che tu ottenga un'implementazione utile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.