Fondamentalmente, non penso che tutti stiano pensando alle giuste linee. Non esiste l'ultima riga qui. L'eccezione viene sollevata dall'interprete quando riceve un'espressione completamente. Secondo la grammatica di Python: http://docs.python.org/reference/grammar.html, l'espressione non è completa fino a quando non si preme una parentesi di chiusura ')'. Joran Beasley ha fornito una breve spiegazione per lo stesso nei commenti contro la domanda stessa.
Si può fare 3 cose fanno giudicare la correttezza di questa, senza scavare molto in profondità nella grammatica: -
scrivere questo codice in Python:
a = (1 + 2 + 0/0 + 4 + 5)
Ciò solleva anche ZeroDivionError.
scrivere questo codice in Python:
a = (1 + 2 + 0/0 + 4 + 5 # e premere enter
Questo ti dà una sintassi non valida poiché l'espressione non è completa e non può essere analizzata dall'interprete PS: Questo è uguale al codice menzionato nella domanda
- scrivere questo codice in Python:
a = (1
+2
+0/0
+4
+5)
Alla fine, l'espressione non viene completata fino a quando non si preme la parentesi di chiusura. Quindi, puoi continuare ad aggiungere altre sotto-espressioni al suo interno senza ottenere alcuna eccezione. Quindi, fondamentalmente, l'interprete non vede tutto questo come numeri di linea; aspetta fino a quando tutte le espressioni (comprese le sotto-espressioni) sono state completate. E, è un flusso di controllo di programmazione appropriato per l'interpete.
PS: perdona la mia formattazione della risposta.
Nuovo edit: -
@ Hayden: Ho pensato che sarebbe stato facile spiegare le sfumature da non scavare troppo in profondità nella grammatica. Ma, per riferimento, sto solo copiando il codice dall'URL: http://nedbatchelder.com/blog/200804/the_structure_of_pyc_files.html
Passi da eseguire: - 1. Scrivere il codice richiesto nella domanda in un file temp.py e salvarlo, quindi, importare temp in un altro file o nell'interprete. Questo creerà temp.pyc 2. Ora, copia e incolla il codice completo nell'URL sopraindicato in byteCodeDetails.py ed esegui il file nel prompt dei comandi come: python byteCodeDetails.py temp.pyc. La show_file funzione verrà chiamata qui e darà il seguente output: -
03f30d0a magia
moddate 458c2e50 (Ven 17 Ago 23:54:05 2012) Codice
argcount 0
nlocals 0 stacksize 3 bandiere codice 0040
640600640200640200151764030017640400175a000064050053 5
LOAD_CONST 6 (3)
3 LOAD_CONST 2 (0)
6 LOAD_CONST 2 (0)
9 BINARY_DIVIDE
10 BINARY_ADD
11 LOAD_CONST 3 (4)
14 BINARY_ADD
15 LOAD_CONST 4 (5)
18 BINARY_ADD
19 store_name 0 (a)
22 LOAD_CONST 5 (nessuna)
25 RETURN_VALUE
const
Nessuno
nomi ('A',)
varnames()
freevars()
cellvars()
nome del file 'C: \ Users \ Python \ temp1.py'
nome ''
firstlineno 5
lnotab
Quindi, come si può notare che: -
- Citazione dal collegamento menzionato sopra: Nell'output disassemblato, i numeri più a sinistra (1, 2, 3) sono i numeri di riga nel file di origine originale e i numeri successivi (0, 3, 6, 9 , ...) sono i byte di offset dell'istruzione. Analogamente, per il tuo codice, il numero più a sinistra è solo 5, che è il numero di riga, e le colonne a destra rappresentano i mnemonici (che devono essere letti dall'interprete) tradotti dal compilatore per il tuo codice. le espressioni sono formate e la loro formazione viene superata dal valore dei numeri di riga nel codice compilato.
- firstlineno punta a 5.
Ora, basta fare un leggero cambiamento nel vostro codice iniziale nel file temp.py: -
a = (1
+2
+0/0
+ 4 +
5)
Ora, esegui ancora una volta i due passaggi precedenti. Quello che segue è l'output: -
magia 03f30d0a
moddate 0f8e2e50 (sab 18 agosto 00:01:43 2012)
codice
argcount 0
nlocals 0
stacksize 3
bandiere 0040
codice 640600640200640200151764030017640400175a000064050053 0 LOAD_CONST 6 (3)
3 LOAD_CONST 2 (0)
6 LOAD_CONST 2 (0)
9 BINARY_DIVIDE
10 BINARY_ADD
11 LOAD_CONST 3 (4)
14 BINARY_ADD
5 15 LOAD_CONST 4 (5)
18 BINARY_ADD
19 STORE_NAME 0 (a)
22 LOAD_CONST 5 (Nessuno)
25 RETURN_VALUE
consts
Nessuno
nomi ('A',)
varnames()
freevars()
cellvars()
nome 'C: \ Users \ Python \ temp1.py'
nome ''
firstlineno 4
lnotab 0f01
Bene, ora y ou può chiaramente vedere 2 cose: -
- Il codice byte è composto da 2 linee illustrate nella riga accanto a 'codice 640600640200640200151764030017640400175a000064050053', con il prefisso '4' e '5'. Questo dimostra che il compilatore ha analizzato il file .py e convertito il codice in temp.py in 2 righe di codice che verranno eseguite dall'interprete.noti che qui il contenuto della linea 4 vengono eseguite dall'interprete non importa l'espressione è completo o meno
- Il valore di modifiche firstlineno a 4 invece di 5
Il punto di questa lunga discussione è che, ovunque il codice byte indichi all'interprete che è qui che inizia una linea e le istruzioni corrispondenti che devono essere eseguite per questa linea, l'interprete esegue quella riga e le istruzioni corrispondenti scritte accanto ad essa.
Il codice nella domanda mostra firstlineno come 5, è per questo che si riceve un errore nella riga 5. Speriamo che questo aiuti ora.
Sai, mi stavo chiedendo la stessa cosa quando ho commentato l'altra domanda. –
In questo caso potrebbe essere stato un altro motivo molto localizzato (ad esempio, potrebbe esserci una differenza tra il file .py e il file .pyc). –
Di solito, è l'ultima riga. Nel caso in cui il codice sorgente e il codice effettivamente in esecuzione non siano sincronizzati, potrebbe essere una linea qualsiasi. Puoi usare 'dis.dis()' per vedere i numeri di riga associati ad ogni istruzione bytecode. –