Python Language
dentellatura
Ricerca…
Errori di indentazione
La spaziatura dovrebbe essere uniforme e uniforme. Il rientro improprio può causare un IndentationError
o fare in modo che il programma faccia qualcosa di inaspettato. Nell'esempio seguente viene IndentationError
un IndentationError
:
a = 7
if a > 5:
print "foo"
else:
print "bar"
print "done"
O se la linea che segue i due punti non è rientrata, verrà generato anche un IndentationError
:
if True:
print "true"
Se si aggiunge indentazione a cui non appartiene, verrà generato un IndentationError
:
if True:
a = 6
b = 5
Se si dimentica di annullare la funzionalità potrebbe essere perso. In questo esempio, viene restituito None
invece del False
atteso:
def isEven(a):
if a%2 ==0:
return True
#this next line should be even with the if
return False
print isEven(7)
Semplice esempio
Per Python, Guido van Rossum ha basato il raggruppamento di affermazioni sul rientro. Le ragioni di ciò sono spiegate nella prima sezione delle "Domande frequenti su Python di design e cronologia" . I due punti, :
, vengono utilizzati per dichiarare un blocco di codice rientrato , come nell'esempio seguente:
class ExampleClass:
#Every function belonging to a class must be indented equally
def __init__(self):
name = "example"
def someFunction(self, a):
#Notice everything belonging to a function must be indented
if a > 5:
return True
else:
return False
#If a function is not indented to the same level it will not be considers as part of the parent class
def separateFunction(b):
for i in b:
#Loops are also indented and nested conditions start a new indentation
if i == 1:
return True
return False
separateFunction([2,3,5,6,1])
Spazi o tabulati?
Il rientro consigliato è di 4 spazi ma è possibile utilizzare tabulazioni o spazi purché coerenti. Non mischiare tab e spazi in Python poiché ciò causerà un errore in Python 3 e può causare errori in Python 2 .
Come l'indentazione è analizzata
Lo spazio bianco viene gestito dall'analizzatore lessicale prima di essere analizzato.
L'analizzatore lessicale utilizza una pila per memorizzare i livelli di indentazione. All'inizio, la pila contiene solo il valore 0, che è la posizione più a sinistra. Ogni volta che inizia un blocco nidificato, il nuovo livello di indentazione viene inserito nello stack e un token "INDENT" viene inserito nel flusso di token che viene passato al parser. Non può mai esserci più di un gettone "INDENT" in una riga ( IndentationError
).
Quando viene rilevata una riga con un livello di indentazione più piccolo, i valori vengono estratti dallo stack fino a quando un valore è in cima, che è uguale al nuovo livello di indentazione (se non viene trovato nessuno, si verifica un errore di sintassi). Per ogni valore spuntato, viene generato un token "DEDENT". Ovviamente, possono essere presenti più token "DEDENT" in fila.
L'analizzatore lessicale salta le righe vuote (quelle che contengono solo spazi bianchi e probabilmente commenti) e non genererà mai token "INDENT" o "DEDENT" per loro.
Alla fine del codice sorgente, i token "DEDENT" vengono generati per ogni livello di rientro rimasto nello stack, fino a quando non viene lasciato solo lo 0.
Per esempio:
if foo:
if bar:
x = 42
else:
print foo
viene analizzato come:
<if> <foo> <:> [0]
<INDENT> <if> <bar> <:> [0, 4]
<INDENT> <x> <=> <42> [0, 4, 8]
<DEDENT> <DEDENT> <else> <:> [0]
<INDENT> <print> <foo> [0, 2]
<DEDENT>
Il parser gestisce i token "INDENT" e "DEDENT" come delimitatori di blocchi.