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

40

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

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

This PEP proposes to add a new set of import hooks that offer better customization of the Python import mechanism. Contrary to the current import hook, a new-style hook can be injected into the existing scheme, allowing for a finer grained control of how modules are found and how they are loaded.

Stiamo prendendo in considerazione l'introduzione di una funzionalità simile a PEP302 in Ruby 2.0 (CRuby 2.0). Voglio fare una proposta che possa persuadere Matz. Attualmente, CRuby può caricare script solo da file system in un modo standard.

Se hai esperienza o considerazione su PEP 302, per favore condividi.

Esempio:

  1. È una grande spec. Non c'è bisogno di cambiarlo.
  2. È quasi buono, ma ha questo problema ...
  3. Se potessi tornare indietro al 2003, cambierei le specifiche in ...
posta Koichi Sasada 26.06.2012 - 07:35
fonte

3 risposte

47

Sono il manutentore del modulo runpy di Python e uno dei manutentori del sistema di importazione corrente. Mentre il nostro sistema di importazione è straordinariamente flessibile, sconsiglio di adottarlo all'ingrosso senza apportare qualche ritocco - a causa di problemi di compatibilità con le versioni precedenti, ci sono molte cose che sono più complicate di quelle che altrimenti avrebbero bisogno di essere.

Una cosa che fa male a PEP 302 in Python è quanto ci è voluto per convertire il sistema di importazione principale in esso. Per la maggior parte di un decennio, chiunque abbia fatto qualcosa di complesso con i ganci di importazione è rimasto bloccato implementando due parti: una che gestisce i caricatori conformi a PEP 302 (come le importazioni zip) e una seconda che gestisce il meccanismo di importazione basato su file system standard. Solo nel prossimo 3.3 la gestione dei caricatori PEP 302 si occuperà anche della gestione dei moduli importati attraverso il meccanismo di importazione standard del file system. Cerca di non ripetere l'errore se puoi evitarlo.

PEP 420 (implementato per Python 3.3) rende alcune aggiunte al protocollo per consentire agli importatori di contribuire con porzioni ai pacchetti dello spazio dei nomi. Corregge anche un problema di denominazione nella definizione dell'API del Finder (sostituendo in modo efficace l'errato "find_module" con il più preciso "find_loader"). Speriamo che tutto questo dovrebbe essere documentato più chiaramente nelle specifiche linguistiche entro il tempo in cui 3.3rc1 si sposta in un paio di settimane.

Un altro notevole problema è che l'approccio documentato specificamente in PEP 302 ha un eccessivo stato globale di processo. Non seguiteci su questo percorso: provate a incapsulare lo stato in un modello di oggetti più coerente, quindi è leggermente più facile 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 compatibile con le versioni precedenti dell'approccio di Python con un migliore incapsulamento dello stato. Se hai un modello di stato incapsulato dall'inizio, puoi definire le tue API di conseguenza ed evitare che importatori e caricatori accedano allo stato globale (invece di 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 utilità di congelamento e utilità di documentazione automatica che estrae docstring). Dal momento che è incredibilmente utile, probabilmente staresti meglio standardizzandolo sin dall'inizio: link (probabilmente lo elevereremo a un'API formalmente specificata 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, si consideri la divisione dell'API "load_module" in passi separati "init_module" e "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 abbiamo fatto che vale la pena di evitare.

    
risposta data 23.07.2012 - 08:12
fonte
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.

Per prima cosa, non affidarti troppo direttamente a PEP 302, ma guarda a ciò che importlib fornisce in termini di classi astratte di base, ecc. Per le compatibilità con le versioni precedenti doveva essere compatibile con PEP 302, ma dovevo aggiungere alcune delle mie API per completare il supporto per una vera flessibilità.

Un altro punto importante è che stai dando agli sviluppatori due elementi di flessibilità. Uno è la possibilità di memorizzare codice in un modo diverso da quello direttamente sul file system come singoli file (io lo chiamo il back-end di storage per le importazioni), ad es. questo permette al codice di vivere in un file zip, database sqlite, ecc. L'altro supporto consiste nel consentire al controllo di pre-elaborare o post-elaborare il codice in qualche modo, ad es. Quixote (https://www.mems-exchange.org/software/quixote/) e il suo uso alternativo di stringhe letterali non assegnati a una variabile sarebbero molto più facili da supportare.

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

Ma poi hai anche bisogno di API che siano specifiche del codice. Come menzionato da Nick, finisci per aver bisogno di API per scoprire quali moduli contiene un pacchetto, ecc. Che non sono specifici dei file. C'è questa strana dualità di avere le API per gestire i moduli in cui hai estratto il concetto di file, ma alla fine hai bisogno di fornire API per accedere ai dati delle risorse simili a file. E non appena si tenta di implementarne uno per quanto riguarda l'altro per evitare la duplicazione, le acque diventano davvero oscure (cioè le persone finiscono per fare affidamento sulla strutturazione del percorso 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 ti ritroverà a dover implementare due API simili, ma a lungo andare sarai migliore.

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

    
risposta data 23.07.2012 - 16:27
fonte
-1

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

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

Dovrei consigliarti a pensare a lungo e duramente sui casi d'angolo. Quindi è probabile che avrai un'implementazione utile.

    
risposta data 23.07.2012 - 06:59
fonte

Leggi altre domande sui tag