Python non garantisce l'uso di punti e virgola per terminare le istruzioni. Quindi perché questo (sotto) è permesso?
import pdb; pdb.set_trace()
Python non garantisce l'uso di punti e virgola per terminare le istruzioni. Quindi perché questo (sotto) è permesso?
import pdb; pdb.set_trace()
Risposte:
Python non richiede punti e virgola per terminare le istruzioni. I punti e virgola possono essere utilizzati per delimitare le istruzioni se si desidera inserire più istruzioni sulla stessa riga.
Ora, perché è permesso? È una semplice decisione di progettazione. Non penso che Python abbia bisogno di questo punto e virgola, ma qualcuno ha pensato che sarebbe stato bello averlo e l'aveva aggiunto al linguaggio.
timeit a = 5; a*a
timeitsignifica? a = 2; a*aè inutile poiché aè ancora 2; dovrebbe esserea = 2; a *= a
http://docs.python.org/reference/compound_stmts.html
Le dichiarazioni composte sono composte da una o più "clausole". Una clausola è composta da un'intestazione e una "suite". Le intestazioni della clausola di una particolare istruzione composta sono tutte allo stesso livello di rientro. Ogni intestazione della clausola inizia con una parola chiave identificativa univoca e termina con due punti. Una suite è un gruppo di istruzioni controllate da una clausola. Una suite può essere una o più istruzioni semplici separate da punto e virgola sulla stessa riga dell'intestazione, seguendo i due punti dell'intestazione, oppure può essere una o più istruzioni rientrate nelle righe successive . Solo quest'ultima forma di suite può contenere istruzioni composte nidificate; quanto segue è illegale, soprattutto perché non sarebbe chiaro a quale clausola se appartenesse una seguente clausola else:
if test1: if test2: print xSi noti inoltre che il punto e virgola si lega più strettamente dei due punti in questo contesto, quindi nell'esempio seguente vengono eseguite tutte o nessuna delle istruzioni di stampa:
if x < y < z: print x; print y; print z
riassumendo:
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)* [";"]
if cond: stmt1; stmt2; stmt3, vengono eseguite tutte o nessuna delle dichiarazioni ".
Python usa il ;come separatore, non un terminatore. Puoi anche usarli alla fine di una riga, il che li fa sembrare un terminatore di istruzioni, ma questo è legale solo perché le istruzioni vuote sono legali in Python - una riga che contiene un punto e virgola alla fine è di due istruzioni, la seconda uno vuoto.
stmt_list ::= simple_stmt (";" simple_stmt)* [";"]
Dopo aver letto le risposte, mi manca ancora un aspetto importante dell'uso del punto e virgola, forse l'unico in cui fa davvero la differenza ...
Quando si lavora in un interprete REPL (la shell interattiva di Python, IDLE, ipython) il valore dell'ultima espressione viene stampato sullo schermo e di solito questo è il comportamento previsto.
Ma in alcuni casi si desidera valutare un'espressione solo per i suoi effetti collaterali, ad esempio per vedere tracciati i risultati della simulazione matplotlib.
In questi casi (probabilmente) non vuoi vedere la schermata di reprs di matplotliboggetti che a volte vengono restituiti da una chiamata a una matplotlibfunzione e, almeno in IPython, una delle possibilità che hai è quella di aggiungere un punto e virgola all'eccessivo istruzione dettagliata , ora IPython vede la riga di input composta da due espressioni, l' matplotlibinvocazione e un'istruzione null, in modo che il valore dell'espressione composta sia Nonee nulla venga stampato sullo schermo dall'interprete (l'altra possibilità è l' assegnazione , come in _ = plot(...)ma lo trovo un po 'più invadente).
IMHO, l'uso del punto e virgola per sopprimere l'output non desiderato nell'interprete è diventato più rilevante in seguito all'introduzione del notebook IPyton, che consente di salvare l'input e l'output, incluso l'output grafico, di una sessione di interprete per la documentazione e l'eventuale riutilizzo .
ipython... Ho modificato la mia risposta per riflettere la tua osservazione.
Come tutti gli altri hanno notato, è possibile utilizzare i punti e virgola per separare le istruzioni. Non è necessario , e non è il solito stile.
Per quanto riguarda il motivo per cui questo è utile, ad alcune persone piace mettere due o più brevi affermazioni davvero banali su una sola riga (personalmente penso che questo trasformi diverse linee banali facilmente scremate in una linea dall'aspetto complesso e rende più difficile vedere che è banale) .
Ma è quasi un requisito quando stai invocando una fodera Python dalla shell python -c '<some python code>'. Qui non puoi usare il rientro per separare le istruzioni, quindi se il tuo liner è davvero un liner doppio, dovrai usare un punto e virgola. E se vuoi usare altri argomenti nel tuo one-liner, dovrai importare sysper arrivare a sys.argv, il che richiede una importdichiarazione separata . per esempio
python -c "import sys; print ' '.join(sorted(sys.argv[1:]))" 5 2 3 1 4
1 2 3 4 5
pythonnella shell: basta estendere il codice tra più righe o utilizzare un ereditario. Tuttavia, ciò non riesce se si desidera che sia un "one-liner". ;)
-c
Mi rendo conto di essere di parte come un vecchio programmatore C, ma ci sono momenti in cui le varie convenzioni di Python rendono le cose difficili da seguire. Trovo che la convenzione di trattino sia un po 'fastidiosa a volte.
A volte, la chiarezza di quando termina un'istruzione o un blocco è molto utile. Il codice C standard spesso legge qualcosa del genere:
for(i=0; i<100; i++) {
do something here;
do another thing here;
}
continue doing things;
dove usi gli spazi bianchi per molta chiarezza - ed è facile vedere dove finisce il ciclo.
Python ti consente di terminare con un punto e virgola (facoltativo). Come notato sopra, ciò NON significa che ci sia un'istruzione da eseguire seguita da un'istruzione 'null'. Quindi, per esempio,
print(x);
print(y);
Equivale a
print(x)
print(y)
Se ritieni che il primo abbia un'istruzione null alla fine di ogni riga, prova - come suggerito - a fare questo:
print(x);;
Emetterà un errore di sintassi.
Personalmente, trovo il punto e virgola per rendere il codice più leggibile quando hai molti annidamenti e funzioni con molti argomenti e / o arg con nomi lunghi. Quindi, a mio avviso, questo è molto più chiaro di altre scelte:
if some_boolean_is_true:
call_function(
long_named_arg_1,
long_named_arg_2,
long_named_arg_3,
long_named_arg_4
);
poiché, per me, ti fa sapere che l'ultimo ')' termina un 'blocco' che correva su molte linee.
Personalmente penso che ci siano molte linee guida in stile PEP, IDE che le impongono e la convinzione che esista "un solo modo Pythonic per fare le cose". Se credi in quest'ultimo, dai un'occhiata a come formattare i numeri: a partire da ora, Python supporta quattro diversi modi per farlo.
Sono sicuro che sarò infiammato da alcuni irriducibili, ma al compilatore / interprete non importa se gli argomenti hanno nomi lunghi o brevi, e - ma per la convenzione di rientro in Python - non si preoccupa degli spazi bianchi. Il problema più grande con il codice è dare chiarezza a un altro essere umano (e anche a te stesso dopo mesi di lavoro) per capire cosa sta succedendo, dove iniziano e finiscono le cose, ecc.
I punti e virgola fanno parte della sintassi valida: 8. Istruzioni composte (The Python Language Reference)
Una citazione da " When Pythons Attack "
Non terminare tutte le dichiarazioni con un punto e virgola. È tecnicamente legale farlo in Python, ma è totalmente inutile a meno che tu non stia posizionando più di un'istruzione su una singola riga (ad esempio, x = 1; y = 2; z = 3).
x,y,z = 1,2,3?
x, y, z = 1, 2, 3sia più lento perché incorre in un inutile round trip di costruzione di una tupla e poi immediatamente la desembla. (A proposito, non credo davvero che @communistpancake stia suggerendo il x=1; y=2; z=3modello. Penso che stia semplicemente dando un esempio di come il punto e virgola è un separatore piuttosto che un terminatore.)
Più istruzioni su una riga possono includere punti e virgola come separatori. Ad esempio: http://docs.python.org/reference/compound_stmts.html Nel tuo caso, facilita l'inserimento di un punto da interrompere nel debugger.
Inoltre, come menzionato da Mark Lutz nel Learning Python Book , è tecnicamente legale (anche se inutile e fastidioso) terminare tutte le tue dichiarazioni con punti e virgola.
I punti e virgola possono essere utilizzati per una riga due o più comandi. Non devono essere usati, ma non sono limitati.
Il punto e virgola (;) consente più istruzioni su una sola riga dato che nessuna delle due istruzioni avvia un nuovo blocco di codice.
http://www.tutorialspoint.com/python/python_basic_syntax.htm
I punti e virgola (come punti, virgole e parentesi) tendono a causare guerre di religione. Tuttavia, essi (o un simbolo simile) sono utili in qualsiasi linguaggio di programmazione per vari motivi.
Pratico: la capacità di mettere diversi comandi brevi che concettualmente si uniscono sulla stessa linea. Un testo del programma che assomiglia a un serpente stretto ha l'effetto opposto di ciò che si intende per newline e rientro, che evidenzia la struttura.
Concettuale: separazione delle preoccupazioni tra la sintassi pura (in questo caso, per una sequenza di comandi) dalla presentazione (ad es. Newline), ai vecchi tempi chiamata "bella stampa".
Osservazione: per evidenziare la struttura, il rientro potrebbe essere aumentato / sostituito da linee verticali in modo ovvio, fungendo da "righello visivo" per vedere dove inizia e termina un rientro. Colori diversi (ad es. Seguendo il codice colore per resistori) possono compensare l'affollamento.
È consentito perché gli autori hanno deciso di consentirlo: https://docs.python.org/2/reference/simple_stmts.html
Se passiamo alla domanda sul perché gli autori abbiano deciso di farlo, immagino che sia così perché la semicolonna è consentita come semplice terminazione delle istruzioni almeno nei seguenti linguaggi: C ++, C, C #, R, Matlab, Perl, ...
Quindi è più veloce passare all'utilizzo di Python per le persone con background in altre lingue. E non vi è alcuna perdita di generalità in tale deicison.
Il punto e virgola (";") è necessario solo per la separazione delle istruzioni all'interno di uno stesso blocco, come se avessimo il seguente codice C:
if(a>b)
{
largest=a; //here largest and count are integer variables
count+=1;
}
Può essere scritto in Python in una delle due forme:
if a>b:
largest=a
count=count+1
O
if a>b: largest=a;count=count+1
Nell'esempio precedente potresti avere un numero qualsiasi di istruzioni all'interno di un ifblocco e può essere separato da ";" anziché.
Spero che niente sia così semplice come sopra spiegato.
Aggiungendo alla vasta conoscenza qui presente,
questa è una risposta relativa alla libreria 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')
Se non si fornisce un punto e virgola alla fine della barra (barra orizzontale), l'output è un grafico + un indirizzo di funzione. Ma se si usano i punti e virgola alla fine di entrambe le linee barh, allora mostra solo la trama e sopprime l'output per l'indirizzo della funzione.
Qualcosa del genere: confronto