¿Por qué se permite el punto y coma en este fragmento de Python?

166

Python no garantiza el uso de punto y coma para finalizar las declaraciones. Entonces, ¿por qué está permitido (a continuación)?

import pdb; pdb.set_trace()
Canada Dry
fuente
1
Tenga en cuenta que dicho código es descaradamente solo para fines de depuración y presumiblemente se eliminará antes de que se "haga". Utilizo ese fragmento tal como lo tienes para poder moverlo fácilmente.
Nick T
Lol Llegué a esta pregunta desde el mismo sitio web: realpython.com/python-debugging-pdb
mackycheese21

Respuestas:

225

Python no requiere punto y coma para terminar las declaraciones. Se pueden usar dos puntos y coma para delimitar las declaraciones si desea colocar varias declaraciones en la misma línea.

Ahora, ¿por qué está permitido? Es una simple decisión de diseño. No creo que Python necesite este punto y coma, pero alguien pensó que sería bueno tenerlo y lo agregó al lenguaje.

André Caron
fuente
16
Es útil para cosas comotimeit a = 5; a*a
endolito
13
Parece útil para las declaraciones ejecutivas, por ejemplo, exec ('para a en [1,2,3]: imprimir a; imprimir a + 1')
Phil C
75
He venido a Python con antecedentes de C, Obj-C, Javascript, PHP. Frecuentemente pongo un terminador (inútil); Al final de una línea. Pero afortunadamente Python me perdona
Paolo
36
El punto y coma es muy útil en el shell django, o el depurador, por lo que puede escribir un pequeño programa en una sola línea y repetirlo más tarde.
Bryce
55
@endolith ¿Qué timeitsignifica? a = 2; a*aes inútil ya aque todavía es 2; tendría que sera = 2; a *= a
Nearoo
58

http://docs.python.org/reference/compound_stmts.html

Las declaraciones compuestas consisten en una o más 'cláusulas'. Una cláusula consiste en un encabezado y una 'suite'. Los encabezados de cláusula de una declaración compuesta particular están todos en el mismo nivel de sangría. Cada encabezado de cláusula comienza con una palabra clave de identificación única y termina con dos puntos. Una suite es un grupo de declaraciones controladas por una cláusula. Una suite puede ser una o más declaraciones simples separadas por punto y coma en la misma línea que el encabezado, siguiendo los dos puntos del encabezado, o puede ser una o más declaraciones sangradas en líneas posteriores . Solo la última forma de suite puede contener sentencias compuestas anidadas; lo siguiente es ilegal, principalmente porque no sería claro a qué cláusula pertenecería una cláusula siguiente:

if test1: if test2: print x

También tenga en cuenta que el punto y coma se une más fuerte que los dos puntos en este contexto, de modo que en el siguiente ejemplo, se ejecutan todas o ninguna de las declaraciones de impresión:

if x < y < z: print x; print y; print z 

Resumiendo:

compound_stmt ::=  if_stmt
                   | while_stmt
                   | for_stmt
                   | try_stmt
                   | with_stmt
                   | funcdef
                   | classdef
                   | decorated
suite         ::=  stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT
statement     ::=  stmt_list NEWLINE | compound_stmt
stmt_list     ::=  simple_stmt (";" simple_stmt)* [";"]
chown
fuente
44
No sabía acerca de la prioridad de que el punto y coma fuera menos que dos puntos después de un if. ¡Gracias!
gaborous
3
@gaborous Personalmente siento que tu comentario es lo suficientemente ambiguo como para hacerme pensar que quieres decir lo contrario. Entonces, para aclarar, prefiero sugerir a otros lectores que se queden con la frase oficial: en ese if cond: stmt1; stmt2; stmt3ejemplo, se ejecutan todas o ninguna de las declaraciones ".
RayLuo
Sí, eso es lo que quise decir, si la prioridad es menor, entonces el lexer no puede abandonar el bloque padre (dos puntos) hasta que se ejecuten todas las declaraciones de punto y coma. Eso realmente no es algo obvio.
Gaborous
38

Python usa el ;como separador, no como terminador. También puede usarlos al final de una línea, lo que los hace parecer un terminador de declaraciones, pero esto es legal solo porque las declaraciones en blanco son legales en Python: una línea que contiene un punto y coma al final son dos declaraciones, la segunda uno en blanco

un poco
fuente
28
Si pones dos puntos y comas al final (o en cualquier lugar), obtienes un SyntaxError. Por lo tanto, parece que las declaraciones en blanco no son del todo legales.
Cucu
10
Probablemente tiene la misma lógica que las listas, las tuplas, los dictados con comas finales son válidos y los mismos que sus contrapartes recortadas (por ejemplo, [1,2,3] == [1,2,3,]) pero no pueden contener comas dobles . Entonces, básicamente, Python tiene un "removedor en blanco final". Que por cierto queda claro de esto:stmt_list ::= simple_stmt (";" simple_stmt)* [";"]
Cucu
@ Cucu Tienes razón. Tampoco puede comenzar una línea con un punto y coma, o comenzar una lista de expresiones con una coma. Por lo tanto, es más exacto decir que los puntos y comas son separadores y terminadores opcionales.
wjandrea
28

Punto y coma en el intérprete

Después de leer las respuestas, todavía extraño un aspecto importante del uso de punto y coma, posiblemente el único en el que realmente hace la diferencia ...

Cuando trabaja en un intérprete REPL (el shell interactivo de Python, IDLE, ipython), el valor de la última expresión se imprime en la pantalla y, por lo general, este es el comportamiento deseado.

Usando una expresión para efectos secundarios

Pero en algunos casos, desea evaluar una expresión solo para sus efectos secundarios, por ejemplo, para ver los resultados de su simulación graficados por matplotlib.

En estos casos, (probablemente) no desea ver la pantalla de reprs de matplotlibobjetos que a veces son devueltos por una llamada a una matplotlibfunción y, al menos en IPython, una de las posibilidades que tiene es agregar un punto y coma al excesivo declaración detallada , ahora IPython ve la línea de entrada como compuesta por dos expresiones, la matplotlibinvocación y una declaración nula, de modo que el valor de la expresión compuesta es Noney el intérprete no imprime nada (la otra posibilidad es la asignación , como en _ = plot(...)pero me parece un poco más intrusivo).

Comentario personal

En mi humilde opinión, el uso del punto y coma para suprimir la salida no deseada en el intérprete se ha vuelto más relevante después de la introducción del cuaderno IPyton, que permite guardar la entrada y la salida, incluida la salida gráfica, de una sesión de intérprete para documentación y reutilización eventual .

gboffi
fuente
Ya veo, gracias por compartir! Esto resolvió exactamente mi problema, donde el punto y coma puede evitar la reproducción por matplotlib en el cuaderno de
ipython
Esta es una característica solo de IPython, y no es una declaración nula, solo una sintaxis especial.
wjandrea
@wjandrea Tienes razón, es solo que ipython... he editado mi respuesta para reflejar tu comentario.
gboffi
12

Como todos han notado, puede usar punto y coma para separar las declaraciones. No tiene que hacerlo, y no es el estilo habitual.

En cuanto a por qué esto es útil, a algunas personas les gusta poner dos o más declaraciones cortas realmente triviales en una sola línea (personalmente creo que esto convierte varias líneas triviales fácilmente descremadas en una línea de aspecto complejo y hace que sea más difícil ver que es trivial) .

Pero es casi un requisito cuando invocas Python one liners desde el shell usando python -c '<some python code>'. Aquí no puede usar sangría para separar las declaraciones, por lo que si su línea única es realmente una línea doble, deberá usar un punto y coma. Y si desea utilizar otros argumentos en su línea única, tendrá que importar syspara llegar sys.argv, lo que requiere una importdeclaración por separado . p.ej

python -c "import sys; print ' '.join(sorted(sys.argv[1:]))" 5 2 3 1 4
1 2 3 4 5
Ben
fuente
2
Usted puede utilizar la sangría y saltos de línea al pasar a través de comandos pythonde la shell: Sólo abarcar el código citado en varias líneas o usar un heredoc. Aún así, eso falla si quieres que sea un "one-liner". ;)
00dani
incluye rasgos para la respuesta ferroviaria con-c
n611x007
6

Me doy cuenta de que estoy sesgado como un viejo programador de C, pero hay momentos en que las diversas convenciones de Python hacen que las cosas sean difíciles de seguir. La convención de sangría me parece un poco molesta a veces.

A veces, la claridad de cuándo termina una declaración o un bloque es muy útil. El código C estándar suele leer algo como esto:

for(i=0; i<100; i++) {
    do something here;
    do another thing here;
}

continue doing things;

donde usa el espacio en blanco para mucha claridad, y es fácil ver dónde termina el bucle.

Python te permite terminar con un punto y coma (opcional). Como se señaló anteriormente, eso NO significa que haya una declaración para ejecutar seguida de una declaración 'nula'. Así por ejemplo,

print(x);
print(y);

Es lo mismo que

print(x)
print(y)

Si cree que el primero tiene una declaración nula al final de cada línea, intente, como se sugiere, hacer esto:

print(x);;

Lanzará un error de sintaxis.

Personalmente, encuentro el punto y coma para que el código sea más legible cuando tienes muchos anidamientos y funciones con muchos argumentos y / o argumentos largos. Entonces, a mi entender, esto es mucho más claro que otras opciones:

if some_boolean_is_true:
    call_function(
        long_named_arg_1,
        long_named_arg_2,
        long_named_arg_3,
        long_named_arg_4
    );

ya que, para mí, te permite saber que el último ')' termina con un 'bloque' que se ejecutó en muchas líneas.

Personalmente, creo que hay mucho o mucho de las pautas de estilo PEP, IDE que las hacen cumplir, y la creencia de que hay "una sola forma pitónica de hacer las cosas". Si crees lo último, ve a ver cómo formatear números: a partir de ahora, Python admite cuatro formas diferentes de hacerlo.

Estoy seguro de que algunos fanáticos me criticarán, pero al compilador / intérprete no le importa si los argumentos tienen nombres largos o cortos, y, pero para la convención de sangría en Python, no le importa el espacio en blanco. El mayor problema con el código es dar claridad a otro ser humano (e incluso a usted mismo después de meses de trabajo) para que entienda lo que está sucediendo, dónde comienzan y terminan las cosas, etc.

eSurfsnake
fuente
5

Una cita de " Cuando las pitones atacan "

No termine todas sus declaraciones con un punto y coma. Es técnicamente legal hacer esto en Python, pero es totalmente inútil a menos que esté colocando más de una declaración en una sola línea (por ejemplo, x = 1; y = 2; z = 3).

Panqueque Comunista
fuente
44
¿Por qué no x,y,z = 1,2,3?
Anirban Nag 'tintinmj'
55
@ AnirbanNag'tintinmj 'En este caso particular, creo que x, y, z = 1, 2, 3es más lento porque incurre en un viaje innecesario de ida y vuelta para construir una tupla y luego la desembarca inmediatamente. (Por cierto, realmente no creo que @communistpancake sugiera el x=1; y=2; z=3patrón. Creo que él / ella simplemente está dando un ejemplo de cómo el punto y coma es un separador en lugar de un terminador).
RayLuo
1
@AnirbanNag - porque eso habría sido un ejemplo de basura de una línea de múltiples declaraciones.
cz
2

Python le permite usar un punto y coma para denotar el final de una declaración si está incluyendo más de una declaración en una línea.

Godwin
fuente
2

Los puntos y comas se pueden usar para una línea, dos o más comandos. No tienen que usarse, pero no están restringidos.

El punto y coma (;) permite múltiples sentencias en la única línea dado que ninguna de las sentencias inicia un nuevo bloque de código.

http://www.tutorialspoint.com/python/python_basic_syntax.htm

cráneo vacío
fuente
2

Los puntos y comas (como puntos, comas y paréntesis) tienden a causar guerras religiosas. Aún así, (o algún símbolo similar) son útiles en cualquier lenguaje de programación por varias razones.

  • Práctico: la capacidad de poner varios comandos cortos que pertenecen conceptualmente juntos en la misma línea. Un texto de programa que parece una serpiente angosta tiene el efecto opuesto de lo que se pretende con las nuevas líneas y la sangría, que es resaltar la estructura.

  • Conceptual: separación de preocupaciones entre sintaxis pura (en este caso, para una secuencia de comandos) de la presentación (por ejemplo, nueva línea), en los viejos tiempos llamada "impresión bonita".

Observación: para resaltar la estructura, la sangría podría ser aumentada / reemplazada por líneas verticales de la manera obvia, sirviendo como una "regla visual" para ver dónde comienza y termina una sangría. Los diferentes colores (p. Ej., Siguiendo el código de color para las resistencias) pueden compensar el hacinamiento.

Raymond
fuente
1

Está permitido porque los autores decidieron permitirlo: https://docs.python.org/2/reference/simple_stmts.html

Si se pasa a la pregunta de por qué los autores decidieron hacer eso, supongo que es así porque la semi-columna está permitida como terminación de declaración simple al menos en los siguientes idiomas: C ++, C, C #, R, Matlab, Perl, ...

Por lo tanto, es más rápido pasar al uso de Python para personas con antecedentes en otro idioma. Y no hay pérdida de generalidad en tal deicison.

bruziuz
fuente
1

El punto y coma (";") solo es necesario para la separación de las declaraciones dentro de un mismo bloque, como si tenemos el siguiente código C:

if(a>b)
{
largest=a;  //here largest and count are integer variables
count+=1;
}

Se puede escribir en Python en cualquiera de las dos formas:

if a>b:   
    largest=a
    count=count+1

O

if a>b:    largest=a;count=count+1

En el ejemplo anterior, puede tener cualquier número de declaraciones dentro de un ifbloque y puede estar separado por ";" en lugar.

Espero que nada sea tan simple como la explicación anterior.

Mohd Asim
fuente
0

Agregando al vasto conocimiento presente aquí,
esta es una respuesta relacionada con la biblioteca matplotlib

import numpy as np
import matplotlib as plt
%matplotlib notebook
linear_data = np.array([1, 2, 3, 4, 5, 6, 7, 8])
quadratic_data = linear_data**2
plt.figure()
xvals = range(len(linear_data))
plt.barh(xvals, linear_data, height = 0.3, color='b')
plt.barh(xvals, quadratic_data, height = 0.3, left=linear_data, color='r')

Si no proporciona un punto y coma al final de la barra (barra horizontal), la salida es un gráfico + una dirección de función. Pero si usa puntos y comas al final de ambas líneas de barras, solo muestra el diagrama y suprime la salida para la dirección de la función.

Algo como esto: Comparación

Farhan Khan
fuente
3
Esto es específico de IPython y no se aplica al REPL de Python estándar.
wjandrea
Creo que este es un ejemplo brillante en el que la forma en que los escritores de idiomas pensaban que estaban introduciendo la simplicidad, el poder y la uniformidad no pudo pensar con anticipación en problemas como este.
eSurfsnake