2009-06-22 21 views
14

Il mio background è C e C++. Mi piace molto Python, ma c'è un aspetto di esso (e altri linguaggi interpretati credo) che è davvero difficile da usare quando sei abituato a lingue compilate.Come posso assicurarmi che tutto il mio codice Python "compili"?

Quando ho scritto qualcosa in Python e sono arrivato al punto in cui posso eseguirlo, non c'è ancora alcuna garanzia che non rimangano errori specifici della lingua. Per me ciò significa che non posso fare affidamento esclusivamente sulla mia difesa runtime (test rigorosi di input, asserzioni ecc.) Per evitare arresti anomali, perché in 6 mesi, quando si esegue un codice altrimenti piacevole, potrebbe rompersi a causa di qualche errore di battitura .

Chiaramente un sistema dovrebbe essere testato abbastanza per assicurarsi che tutto il codice sia stato eseguito, ma la maggior parte delle volte utilizzo Python per script interni e piccoli strumenti, che naturalmente non ricevono l'attenzione QA di cui hanno bisogno. Inoltre, alcuni codici sono così semplici che (se il tuo background è C/C++) sai che funzionerà bene finché compila (ad esempio metodi getter all'interno delle classi, di solito un semplice ritorno di una variabile membro).

Quindi, la mia domanda è ovvia: c'è un modo (con uno strumento speciale o qualcosa del genere) posso essere sicuro che tutto il codice nel mio script Python verrà "compilato" ed eseguito?

+0

Bello ... Sono un ragazzo C/C++ nuovo anche per Python, e questo problema mi ha frustrato fino alla fine. Non ho mai pensato di chiedere una soluzione, non pensavo che potesse esistere. –

risposta

21

Guardate PyChecker e PyLint.

Ecco esempio di uscita da pylint , derivante dal programma di banale:

print a 

Come si può vedere, si rileva la variabile non definita, che py_compile no (volutamente)

in foo.py: 

************* Module foo 
C: 1: Black listed name "foo" 
C: 1: Missing docstring 
E: 1: Undefined variable 'a' 


... 

|error  |1  |1  |=   | 
. 10

banale esempio del perché i test non sono abbastanza buone, anche se riguardano "ogni linea":

bar = "Foo" 
foo = "Bar" 
def baz(X): 
    return bar if X else fo0 

print baz(input("True or False: ")) 

EDIT: PyChecker gestisce il ternario per me:

Processing ternary... 
True or False: True 
Foo 

Warnings... 

ternary.py:6: No global (fo0) found 
ternary.py:8: Using input() is a security problem, consider using raw_input() 
+1

Buona raccomandazione di pychecker e pylint. pyflakes è anche buono perché è molto veloce, e la versione del tronco svn catturerà le variabili locali inutilizzate. Per quanto riguarda il test di "ogni linea", penso che dovresti almeno testare ogni "percorso". Questo avrebbe catturato il tuo esempio di esplosione. –

+1

Funziona alla grande Matthew, grazie! – sharkin

+0

È impossibile identificare (e quindi testare) ogni possibile percorso logico, poiché ciò equivale al problema dell'arresto (http://en.wikipedia.org/wiki/Code_coverage). –

1

Penso che quello che stai cercando sia la copertura della linea di test del codice. Vuoi aggiungere test al tuo script per assicurarti che tutte le tue linee di codice, o tutte le volte che hai tempo, vengano testate. Il test è una grande mole di lavoro, ma se si desidera che il tipo di certezza si sta chiedendo, non c'è il pranzo libero, mi dispiace :(.

+1

Non sta cercando il codice per superare i test. Ha già detto, "in 6 mesi, quando il bel codice è finalmente funzionante, potrebbe semplicemente crearsi a causa di alcuni errori di battitura". I test controllano se il codice fa "la cosa giusta" per alcuni set di input finiti, non se utilizza una sintassi valida in tutto (cosa l'OP vuole) –

+1

Non supererà molti test se ha errori di battitura. Se la tua copertura tocca ogni riga di codice (non ogni percorso logico), sarai ragionevolmente sicuro che funzionerà in modo affidabile. –

+0

-1. Mi dispiace Adam, la domanda suggerisce che gli sforzi del QA sono piuttosto irrealistici, quindi la risposta è di poco aiuto. – sharkin

0

Il codice in realtà viene compilato quando lo esegui, il runtime di Python si lamenterà se c'è un errore di sintassi nel codice. Rispetto ai linguaggi compilati staticamente come C/C++ o Java, non controlla se i nomi e i tipi delle variabili sono corretti, per cui è necessario eseguire effettivamente il codice (ad es. Con test automatici).

+1

-1. Sembra che ci siano effettivamente degli strumenti per scoprire errori del genere, quindi non è necessario eseguire realmente il codice per scoprirli. – sharkin

1

Se si utilizza Eclipse con Pydev come IDE, è possibile contrassegnare immediatamente molti errori di battitura con gli squigglie rossi e dispone anche dell'integrazione di Pylint. Ad esempio:

foo = 5 
print food 

verrà contrassegnato come "Variabile non definita: cibo". Naturalmente questo non è sempre accurato (forse il cibo è stato definito in precedenza usando setattr o altre tecniche esotiche), ma funziona bene la maggior parte del tempo.

In generale, è possibile analizzare il codice solo in modo statico in modo che il codice sia effettivamente statico; più il tuo codice è dinamico, più hai davvero bisogno di test automatici.

2

Altri hanno menzionato strumenti come PyLint che sono piuttosto buoni, ma il lungo e il corto è che semplicemente non è possibile fare il 100%. In effetti, potresti anche non volerlo fare. Una parte del vantaggio della dinamicità di Python è che puoi fare cose pazzesche come inserire i nomi nello scope locale attraverso un accesso al dizionario.

In base a ciò, se si desidera rilevare gli errori di tipo in fase di compilazione, non utilizzare Python. Una scelta linguistica comporta sempre una serie di compromessi. Se scegli Python su C, tieni presente che stai scambiando un sistema di tipo forte per uno sviluppo più veloce, una migliore manipolazione delle stringhe, ecc.

Problemi correlati