Fundamentalmente, no creo que todos estemos pensando en la línea correcta. No hay tal cosa como la última línea aquí. La excepción la plantea el intérprete cuando recibe una expresión completa. De acuerdo con la gramática de Python: http://docs.python.org/reference/grammar.html, la expresión no está completamente completa hasta que tocas un corchete de cierre ')'. Una breve explicación de lo mismo fue dada por Joran Beasley en los comentarios en contra de la pregunta en sí.
Puede hacer 3 cosas hacen juzgar la exactitud de esta, sin ahondar más profundamente en la gramática: -
escribir este código en el intérprete de Python:
a = (1 + 2 + 0/0 + 4 + 5)
Esto también plantea ZeroDivionError.
escribir este código en el intérprete de Python:
a = (1 + 2 + 0/0 + 4 + 5 # Y, enter
Este le da una sintaxis inválida ya que la expresión no está completa y no puede ser analizada por el intérprete PD: Este es el mismo que el código mencionado en la pregunta
- escribir este código en el intérprete Python:
a = (1
+2
+0/0
+4
+5)
Finalmente, la expresión no se completa hasta que tocas el corsé de cierre. Por lo tanto, puede continuar agregando más sub expresiones dentro de él sin obtener ninguna excepción. Por lo tanto, fundamentalmente, el intérprete no ve todo esto como números de línea; espera hasta que se hayan completado todas las expresiones (incluidas las subexpresiones). Y, es un flujo de control de programación apropiado para el interperador.
PD: Perdone el formato de la respuesta.
Nueva edición: -
@ Hayden: pensé que sería fácil de explicar las sutilezas por no ahondar demasiado profundamente en la gramática. Pero, para su referencia, solo estoy copiando el código de la URL: http://nedbatchelder.com/blog/200804/the_structure_of_pyc_files.html
Pasos a seguir: - 1. Escriba el código que se le pide en la pregunta en un archivo temp.py y guárdelo, luego, importe la temperatura en otro archivo o en el intérprete. Esto creará temp.pyc 2. Ahora, copie y pegue el código completo en la URL mencionada en byteCodeDetails.py y ejecute el archivo en el símbolo del sistema como: python byteCodeDetails.py temp.pyc. El show_file función será llamada aquí y dará el siguiente resultado: -
03f30d0a magia
moddate 458c2e50 (Vie Ago 17 de 2012 23:54:05) Código
argcount 0 0
nlocals stacksize 3 banderas código 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 (ninguno)
25 RETURN_VALUE
consts
Ninguno
nombres ('A',)
nombres de variables()
freevars()()
cellvars
nombre de archivo 'C: \ Users \ Python \ temp1.py'
nombre de ''
firstlineno 5
lnotab
lo tanto, como se puede observar que: -
- Citando desde el enlace mencionado anteriormente: En la salida desmontada, los números más a la izquierda (1, 2, 3) son los números de línea en el archivo fuente original y los siguientes números (0, 3, 6, 9 , ...) son los offsets de bytes de la instrucción. De manera similar, para su código, el número más a la izquierda es solo 5, que es el número de línea, y las columnas a la derecha representan los mnemónicos (para ser leídos por el intérprete) traducidos por el compilador para su código. se forman expresiones y su formación es superada por el valor de los números de línea en el código compilado.
- firstlineno señala a 5.
Ahora, basta con un ligero cambio en su código inicial en el archivo temp.py: -
a = (1
+2
+0/0
+ 4 +
5)
Ahora, ejecute los 2 pasos anteriores una vez más. La siguiente es la salida: -
03f30d0a magia
moddate 0f8e2e50 (Sab Ago 18 de 2012 00:01:43)
código
argcount 0 0
nlocals
stacksize 3
banderas 0040
código 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 (Ninguno)
25 RETURN_VALUE
consts
Ninguno
nombres ('a',)
nombres de variables()
freevars()
cellvars()
nombre de archivo 'C: \ Usuarios \ Python \ temp1.py'
nombre de ''
firstlineno 4
lnotab 0F01
Pues bien, ahora y ou puede ver claramente 2 cosas: -
- El código byte se compone de 2 líneas que se muestran en la siguiente línea a 'código 640600640200640200151764030017640400175a000064050053', con el prefijo '4' y '5'. Esto muestra que el compilador ha analizado el archivo .py y convertido el código en temp.py en 2 líneas de código que serán ejecutadas por el intérprete.Tenga en cuenta que aquí el contenido de la línea 4 serán ejecutadas por el intérprete no importa la expresión es completa o no
- El valor de cambios firstlineno a 4 en lugar de 5
El punto de esta larga discusión es que siempre que el código de bytes indica al intérprete que aquí es donde comienza una línea y las declaraciones correspondientes que se deben ejecutar para esta línea, entonces, el intérprete simplemente ejecuta esa línea y las declaraciones correspondientes escritas a su lado.
El código en su pregunta muestra firstlineno como 5, es por eso que recibe un error en la línea 5. Es de esperar que esto ayude ahora.
Ya sabes, me preguntaba lo mismo cuando comencé la otra pregunta. –
En ese caso, podría haber sido otra razón muy localizada (por ejemplo, podría haber una diferencia entre el archivo .py y el archivo .pyc). –
Por lo general, es la última línea. En caso de que el archivo de origen y el código en ejecución realmente no estén sincronizados, podría ser cualquier línea. Puede usar 'dis.dis()' para ver los números de línea asociados con cada instrucción bytecode. –