2015-10-08 16 views
9

Trasferirsi in pitone con C/Java sfondo, di recente ho dovuto implementare una ricorsione mutua, ma qualcosa in python mi dà fastidio:In che modo Python implementa la ricorsione reciproca?

dal momento che un programma Python è interpretato riga per riga, se ho due funzioni una dopo l'altra nello stesso file python:

def A(n): 
    B(n-1) 
# if I add A(1) here, it gives me an error 
def B(n): 
    if n <= 0: 
     return 
    else: 
     A(n-1) 

Quando l'interprete sta leggendo A, B non è ancora definita, ma questo codice non non mi danno un errore

TL; DR mia comprensione è che, quando def viene interpretato, pitone aggiunge una voce un pò di spazio nome locale locals() con {"function name": function address}, ma come per il corpo della funzione, solo fare un controllo della sintassi:

def A(): 
    blabla # this will give an error 

def B(): 
    print x # even though x is not defined, this does not give an error 
    A()  # same as above, NameError is only detected during runtime 
+3

Un errore "SyntaxError" verrà catturato in fase di compilazione, ma la maggior parte degli altri errori ('NameError',' ValueError', ecc.) Verranno rilevati solo in fase di esecuzione e solo se tale funzione viene chiamata. – TigerhawkT3

+1

abbastanza facile da controllare non è vero? 'def f(): sytax error' produce un errore ... – yurib

risposta

4

A SyntaxError verrà catturato in fase di compilazione, ma la maggior parte degli altri errori (NameError, ValueError, ecc.) Verranno rilevati solo in fase di esecuzione e solo se viene chiamata tale funzione.

"se ho scritto una funzione, se non è stata chiamata nel mio test .." - ed è per questo che dovresti testare tutto.

Alcuni IDE generano avvisi in varie situazioni, ma l'opzione migliore è comunque quella di condurre test approfonditi da soli. In questo modo, puoi anche verificare la presenza di errori derivanti da fattori come l'input dell'utente, che i controlli automatizzati di un IDE non copriranno.

+0

Ho appena scoperto che Python può compilare WOW ... ma perché python non controlla NameError in fase di compilazione?qualcosa come ** def A(): print x ** può essere facilmente rilevato senza allocare effettivamente memoria (si sa come compilatore c/C++) – watashiSHUN

+0

[questo metodo per verificare la sintassi] (http://stackoverflow.com/questions/4284313/how-can-i-check-the-syntax-of-python-script-senza-executing-it) produce anche codice binario ... se tutto _compile_ controlla la sintassi, vuol dire che l'output binario potrebbe avere molto di errori e quindi inutile? – watashiSHUN

+0

Anche altre lingue possono avere errori di runtime non rilevati. Ad esempio, in Java è possibile digitare a un tipo errato e il compilatore non si lamenterà. Questo è il motivo per cui dovresti testare correttamente il tuo programma, in modo che non "abbia molti errori" e si rivelino "inutili". – TigerhawkT3

4

La riga B(n-1) dice "quando viene eseguita questa istruzione, cercare una funzione B nell'ambito del modulo, quindi chiamarla con i parametri n-1". Poiché la ricerca avviene quando viene eseguita la funzione, è possibile definire in seguito B.

(Inoltre, è possibile sovrascrivere completamente B con una funzione diversa, e A chiamerà la nuova B dopo. Ma questo può portare a un codice di confusione.)

Se siete preoccupati di non prendere le chiamate a funzioni inesistenti, puoi provare a utilizzare gli strumenti di analisi statica. Oltre a questo, assicurati di testare il tuo codice.

0

Quando l'interprete sta leggendo A, B non è ancora definita, ma questo codice non mi dà un errore

Il motivo per cui interprete Python non dà un errore può essere trovato da docs , che è chiamato tecnicamente:

La risoluzione dei nomi delle variabili libere si verifica in fase di runtime, non in fase di compilazione.