Strategia per tenere il passo con (Python) cambi di lingua


16

Scrivere codice che durerà ancora anni

I linguaggi di programmazione cambiano. Le biblioteche cambiano. Alcuni codici di 5, 10 o anche 20 anni fa potrebbero ancora essere eseguiti e produrre risultati previsti, mentre alcuni di 2 anni potrebbero non riuscire con un errore di sintassi. Ciò è in parte inevitabile, poiché le lingue si evolvono (almeno, la maggior parte lo fanno). Gli sviluppatori hanno la responsabilità di mantenere il proprio codice. Ma a volte, la stabilità è un requisito importante nel codice di produzione e il codice dovrebbe semplicemente funzionare per 10 anni senza la necessità che qualcuno lo analizzi ogni anno per adattarlo alle modifiche della lingua. Oppure potrei avere piccoli script, ad esempio per l'analisi dei dati scientifici, che devo rivisitare dopo non toccarli per anni. Ad esempio, negli uffici meteorologici esiste un sacco di codice operativo Fortran anche per le parti non essenziali per la velocità e la stabilità del codice è uno dei motivi. IO' ho sentito la paura dell'instabilità è uno degli oggetti che hanno contro il passaggio a Python (a parte l'inerzia del linguaggio ovviamente; è possibile solo per il nuovo codice non dipendente dal vecchio codice). Naturalmente, una strategia per il codice stabile è quella di bloccare l'intero sistema operativo. Ma ciò non è sempre fattibile.

Sto usando Python come esempio, ma il problema non è limitato a Python in particolare.

Documenti su problemi di compatibilità con Python

Nel caso di Python, ci sono diversi documenti che descrivono la politica per le modifiche incompatibili con le versioni precedenti.

PEP-5

Secondo PEP 5 :

Ci deve essere almeno un periodo di transizione di un anno tra il rilascio della versione transitoria di Python e il rilascio della versione incompatibile con le versioni precedenti. Gli utenti avranno almeno un anno per testare i loro programmi e migrarli dall'uso del costrutto deprecato a quello alternativo.

Personalmente, ritengo che un anno sia piuttosto breve. Significa che potrei scrivere un po 'di codice e tra 1 anno e mezzo non funzionerà più.

PEP 291

PEP 291 contiene un elenco incompleto di linee guida di cose che dovrebbero essere evitate per mantenere la retrocompatibilità. Tuttavia, si riferisce solo a Python 2.x. Poiché Python 2.7 è la versione finale della serie 2.xe Python 2.7 è solo bugfix, questo PEP è ora solo di interesse storico.

PEP 387

Esiste anche PEP 387 su modifiche incompatibili con le versioni precedenti. PEP 387 è una bozza e non una politica ufficiale. Nel giugno 2009, questo è stato discusso sulla mailing-list Python-ideas . Parte della discussione si è focalizzata sul modo in cui gli sviluppatori possono scrivere codice robusto contro i cambiamenti di lingua. Un post ha elencato alcuni consigli su cosa non fare :

Insieme a questo ci sono diverse regole che puoi dedurre che sono probabilmente vere per la maggior parte del tempo: non chiamare cose che iniziano con "_", non scimmiottare nulla, non usare la sostituzione dinamica di classe su oggetti di classi diverse dalla tua , non dipendere dalla profondità delle gerarchie di ereditarietà (ad esempio no ".__bases__[0].__bases__[0]"), assicurarsi che i test vengano eseguiti senza produrre DeprecationWarnings, tenere presente i potenziali conflitti dello spazio dei nomi quando si aggiungono attributi a classi ereditate da altre librerie. Non penso però che tutte queste cose siano scritte in un unico posto.

Inoltre, c'erano alcuni punti su "campi minati" (nuove funzionalità che potrebbero cambiare) e "aree congelate" (API molto vendute garantivano praticamente di non cambiare). Citando Antoine Pitrou :

Penso che l '"area congelata" debba essere definita positivamente (API pubbliche esplicite e comportamento esplicitamente garantito) piuttosto che negativamente (un "campo minato" esplicito). Altrimenti, dimenticheremo di mettere alcune cose importanti nel campo minato e di essere morsi più tardi quando avremo bisogno di cambiarle in modo incompatibile con le versioni precedenti.

Non sembra esserci alcuna conclusione da questo thread, ma si avvicina molto al nucleo di ciò che sto cercando. Il thread ha quasi quattro anni, quindi forse la situazione è cambiata o migliorata. Quale tipo di codice è probabile che sopravviva e quale tipo di codice è più fragile?

Linee guida per il porting

Oltre ai documenti delineati sopra, ogni versione di Python include una linea guida per il porting : porting su Python 3.2 , porting su Python 3.3 , ecc.

Utile compatibilità

PEP 3151 mi ha fatto conoscere il concetto di utile compatibilità . Nelle mie parole, ciò si riduce all'idea che solo se il codice è scritto con cura, gli sviluppatori di lingue devono fare attenzione a mantenere la compatibilità. In realtà non definisce la compatibilità utile , ma penso che sia simile alle idee che ho citato dalla discussione di PEP 387 sopra.

Dal punto di vista dei programmatori

Come programmatore, so che Python cambierà in futuro e che le persone - in particolare me stesso - proveranno a eseguire il mio codice forse tra qualche anno in una versione di Python che è una, due o forse tre versioni minori. Non tutto sarà compatibile, e in effetti è facile trovare un codice che fallirà (una volta ho riscontrato la dichiarazione del codice if sys.version[:3] != '2.3': print 'Wrong version, exiting'). Quello che sto cercando è una serie di linee guida su cosa fare e cosa non fare per migliorare le possibilità che il mio codice continuerà a funzionare inalterato in futuro.

Ci sono delle linee guida di questo tipo? Come faccio a scrivere il codice Python che verrà comunque eseguito in futuro?

La mia domanda riguarda sia il nucleo Python, alla sua libreria standard, ma anche di uso comune add-on biblioteche, in particolare numpy, scipy, matplotlib.


EDIT : finora, due delle risposte si riferiscono a python2 vs. python3. Questo non è ciò che intendo. Conosco strumenti per migrare da Python2 a Python3. La mia domanda riguarda i cambi di lingua ancora da venire . Possiamo fare meglio di una sfera di cristallo nel trovare linee guida per la codifica più stabili. Per esempio:

  • import moduleè più a prova di futuro di from module import *, perché quest'ultimo può rompere il codice se modulecresce una o più nuove funzioni / classi.

  • L'uso di metodi non documentati può essere meno a prova di futuro rispetto all'utilizzo di metodi documentati, poiché qualcosa che non è documentato può essere un segno di qualcosa che non è ancora stabile.

È questo tipo di consigli pratici sulla codifica che sto cercando. Poiché si tratta di presente → futuro, possiamo limitarci a Python3, perché Python2 non cambierà più.

Risposte:


13

Questo è un problema irrisolto nel nostro campo. Non c'è modo di essere sicuri che il codice funzioni a tempo indeterminato. Anche se il tuo codice era davvero perfetto in senso compatibile con il futuro (e se lo è, per favore, vieni a lavorare per la mia azienda!;)), Se viene eseguito, utilizza o viene utilizzato da qualsiasi altro software che ottiene un bug o cambia in ogni caso, il tuo codice potrebbe non funzionare.

Quindi non posso darti un elenco di cose da fare che, se le segui, garantiranno il successo. Ma quello che puoi fare è minimizzare il rischio di rotture future e minimizzare i loro impatti. Un Pythonist più esperto sarebbe in grado di darti consigli più specifici su Python, quindi dovrò essere più generale:

  • scrivere test unitari. Anche per cose che sai non ne hanno bisogno.

  • utilizzando librerie e tecnologie popolari / ben progettate / stabili, evitando quelle impopolari (e quindi probabilmente presto non supportate)

  • evitare di scrivere codice che sfrutti i dettagli di implementazione. Codice per interfacce, non implementazioni. Codice rispetto a più implementazioni della stessa interfaccia. Ad esempio, esegui il codice in CPython, Jython e IronPython e guarda cosa succede. Questo ti darà un ottimo feedback sul tuo codice. Questo potrebbe non essere utile per Python3 - l'ultima volta che ho sentito, alcune implementazioni erano ancora in Python2.

  • scrivere un codice semplice e chiaro che sia esplicito sui suoi presupposti

  • scrivere un codice componibile e componibile. Se un codice deve fare qualcosa di pericoloso (nel senso del futuro), separalo in modo che anche se debba cambiare, il resto del codice non lo fa.

  • avere una specifica di qualche forma. Questo è simile ai punti sui test unitari, se si utilizzano i test come specifiche e le interfacce, che possono anche essere utilizzate come specifiche. (Intendo l'interfaccia in senso generale, non il significato della parola chiave Java).

Fare una di queste cose può / aumenterà la quantità di lavoro che devi fare. Penso che abbia un senso: molti di questi punti possono anche essere fatti su come scrivere un buon codice, il che è abbastanza difficile (secondo me). A volte potresti dover violare alcuni di questi suggerimenti. Questo è perfettamente accettabile, ma attenzione ai costi.

È fantastico che il team di Python stia pensando a questo, e di sicuro sono molto più talentuosi e abili di quanto io sia mai stato. Tuttavia, stimerei che c'è un 100% che il codice di qualcuno da qualche parte smetterà di funzionare nel modo in cui è previsto quando Python viene aggiornato.


4

Si chiama Gestione della configurazione. Se il sistema non viene mai modificato, non dovrebbe rompersi. Quindi non cambiare il sistema. Sei preoccupato per le nuove versioni di Python? Non aggiornare. Preoccupato per i nuovi driver di dispositivo? Non aggiornare. Preoccupato per le patch di Windows? ...


0

Per Python 2 -> Python 3, è già installata una libreria Python 2to3 (viene fornita con il pacchetto Python originale).

Sulla base di ciò, subito dopo il rilascio delle nuove versioni, ci dovrebbero essere librerie simili fornite con ogni nuova versione. Tuttavia, come affermato da Martijn, librerie come queste verranno rilasciate solo per le versioni principali (come la versione 3.0) ma non per le versioni secondarie (come la 3.2). Tuttavia, tra 3.0 e 3.2 (o qualsiasi altra versione minore), non dovrebbero esserci problemi di compatibilità, quindi la conversione in versione 3.0 dovrebbe andare bene.

Inoltre, ti suggerisco di guardare questa domanda .


1
No, 2to3 ti aiuta solo ad aggiornare il codice attraverso il gap della versione principale; non ci sono librerie (necessarie) per aggiornare il codice tra le versioni secondarie.
Martijn Pieters,

@MartijnPieters Le versioni minori non dovrebbero avere problemi di compatibilità, in quanto non dovrebbero esserci cambiamenti eccessivamente grandi. Se ci sono problemi di compatibilità e grandi cambiamenti, dovrebbe essere rilasciata una versione completamente nuova.

0

Non ho molto da aggiungere, il "programma per 2 e usa 2to3" sembra essere un componente aggiuntivo comune su Internet ultimamente. Tuttavia c'è qualcosa che dovresti guardare:

Si chiama sei (pagina pypi) . È una libreria Python dedicata ad aiutare a scrivere codice che funziona sia su Python 2 che su Python 3. L'ho visto impiegato in numerosi progetti mentre sfogliavo la rete, ma al momento i nomi mi sfuggono.


Non proprio quello che sto cercando. Ho modificato la domanda, spero sia più chiaro quello che sto cercando ora.
Gerrit,
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.