Mengapa titik koma diizinkan dalam cuplikan python ini?

166

Python tidak menjamin penggunaan titik koma untuk mengakhiri pernyataan. Jadi mengapa ini (di bawah) diizinkan?

import pdb; pdb.set_trace()
canadadry
sumber
1
Perhatikan bahwa kode tersebut hanya untuk keperluan debugging dan mungkin akan dikeluarkan sebelum "selesai". Saya menggunakan cuplikan itu seperti yang Anda miliki sehingga saya dapat dengan mudah memindahkannya.
Nick T
Lol Saya datang ke pertanyaan ini dari situs web yang sama: realpython.com/python-debugging-pdb
mackycheese21

Jawaban:

225

Python tidak memerlukan semi-titik dua untuk mengakhiri pernyataan. Semi titik dua dapat digunakan untuk membatasi pernyataan jika Anda ingin meletakkan beberapa pernyataan pada baris yang sama.

Sekarang, mengapa ini diizinkan? Ini keputusan desain yang sederhana. Saya tidak berpikir Python membutuhkan hal semi-kolon ini, tetapi seseorang berpikir itu akan baik untuk memiliki dan menambahkannya ke bahasa.

André Caron
sumber
16
Ini berguna untuk hal-hal sepertitimeit a = 5; a*a
endolith
13
Tampaknya berguna untuk pernyataan exec misalnya exec ('untuk dalam [1,2,3]: cetak a; cetak a + 1')
Phil C
75
Saya datang ke Python dengan latar belakang C, Obj-C, Javascript, PHP. Saya sering meletakkan terminator (tidak berguna); di akhir baris. Tapi untungnya Python memaafkan saya
Paolo
36
Tanda titik koma sangat berguna dalam shell Django, atau debugger, sehingga Anda dapat menulis sebuah program kecil pada satu baris dan mengulanginya nanti.
Bryce
5
@ endolith Apa timeitartinya? a = 2; a*atidak berguna karena amasih 2; itu harusa = 2; a *= a
Nearoo
58

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

Pernyataan majemuk terdiri dari satu atau lebih 'klausa.' Klausa terdiri dari header dan 'suite.' Header klausa dari pernyataan majemuk tertentu semuanya pada tingkat indentasi yang sama. Setiap header klausa dimulai dengan kata kunci pengidentifikasi unik dan diakhiri dengan tanda titik dua. Suite adalah sekelompok pernyataan yang dikendalikan oleh klausa. Sebuah suite dapat berupa satu atau lebih pernyataan sederhana yang dipisahkan dengan titik koma pada baris yang sama dengan header, mengikuti titik dua header, atau dapat berupa satu atau lebih pernyataan indentasi pada baris berikutnya . Hanya bentuk suite terakhir yang bisa berisi pernyataan gabungan bersarang; berikut ini adalah ilegal, sebagian besar karena tidak akan jelas di mana jika klausa klausa berikut milik lainnya:

if test1: if test2: print x

Perhatikan juga bahwa tanda koma lebih mengikat daripada titik koma dalam konteks ini, sehingga dalam contoh berikut, semua atau tidak ada pernyataan cetak dieksekusi:

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

Meringkas:

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)* [";"]
dikunyah
sumber
4
Tidak tahu tentang prioritas titik koma yang kurang dari titik dua setelah sebuah if. Terima kasih!
Gaborous
3
@ rumit Saya pribadi merasakan komentar Anda cukup ambigu untuk membuat saya berpikir Anda akan bermaksud sebaliknya. Jadi, untuk memperjelas, saya lebih suka menyarankan pembaca lain untuk tetap dengan frasa resmi: dalam if cond: stmt1; stmt2; stmt3contoh itu, semua atau tidak ada pernyataan dieksekusi ".
RayLuo
Yap itulah yang saya maksudkan, jika prioritasnya lebih rendah, maka lexer tidak dapat meninggalkan blok induk (titik dua) sampai semua pernyataan titik koma dijalankan. Itu benar-benar bukan hal yang jelas.
Gaborous
38

Python menggunakan ;sebagai pemisah, bukan terminator. Anda juga dapat menggunakannya di akhir baris, yang membuat mereka tampak seperti terminator pernyataan, tetapi ini sah hanya karena pernyataan kosong legal di Python - baris yang berisi tanda titik koma di akhir adalah dua pernyataan, yang kedua satu kosong.

baik hati
sumber
28
Jika Anda meletakkan titik koma ganda di akhir (atau di mana saja), Anda mendapatkan SyntaxError. Jadi sepertinya pernyataan kosong tidak sepenuhnya legal.
Cucu
10
Mungkin memiliki logika yang sama dengan daftar, tupel, dikt dengan koma jejak yang valid dan sama dengan rekan-rekan mereka yang dipangkas (mis. [1,2,3] == [1,2,3,]) tetapi mereka tidak dapat mengandung koma ganda . Jadi pada dasarnya Python memiliki "trailing blank remover". Yang jelas dari ini:stmt_list ::= simple_stmt (";" simple_stmt)* [";"]
Cucu
@Cucu Kamu benar. Anda juga tidak dapat memulai garis dengan tanda titik koma, atau memulai daftar ekspresi dengan koma. Jadi lebih akurat untuk mengatakan bahwa titik koma dan koma adalah pemisah dan terminator opsional.
wjandrea
28

Titik koma di dalam interpreter

Setelah membaca jawabannya, saya masih merindukan satu aspek penting menggunakan titik koma, mungkin satu-satunya di mana itu benar-benar membuat perbedaan ...

Ketika Anda bekerja dalam REPL interpreter (shell interaktif Python, IDLE, ipython) nilai ekspresi terakhir dicetak ke layar dan biasanya ini adalah perilaku yang dimaksud.

Menggunakan ekspresi untuk efek samping

Tetapi dalam beberapa kasus Anda ingin mengevaluasi ekspresi untuk efek sampingnya saja, misalnya, untuk melihat hasil simulasi yang Anda buat matplotlib.

Dalam kasus ini Anda (mungkin) tidak ingin melihat screenful dari reprs dari matplotlibbenda-benda yang kadang-kadang dikembalikan oleh panggilan ke matplotlibfungsi dan, di IPython setidaknya, salah satu kemungkinan yang Anda miliki adalah untuk menambahkan titik koma untuk terlalu pernyataan verbose , sekarang IPython melihat baris input sebagai terdiri dari dua ekspresi, matplotlibdoa dan pernyataan nol, sehingga nilai ekspresi majemuk adalah Nonedan tidak ada yang dicetak ke layar oleh penerjemah (kemungkinan lain adalah penugasan , seperti pada _ = plot(...)tapi saya menemukan itu sedikit lebih mengganggu).

Komentar pribadi

IMHO, penggunaan titik koma untuk menekan output yang tidak diinginkan dalam juru bahasa menjadi lebih relevan setelah pengenalan notebook IPyton, yang memungkinkan untuk menyimpan input dan output, termasuk output grafis, dari sesi juru bahasa untuk dokumentasi dan akhirnya digunakan kembali. .

gboffi
sumber
Begitu ya, terima kasih sudah berbagi! Ini baru saja memecahkan masalah saya, di mana titik koma dapat mencegah repr oleh matplotlib di notebook ipython
Napitupulu Jon
Ini adalah fitur khusus IPython, dan ini bukan pernyataan nol, hanya sintaksis khusus.
wjandrea
@wjandrea Anda benar, hanya saja ipython... Saya telah mengedit jawaban saya untuk mencerminkan ucapan Anda.
gboffi
12

Seperti yang dicatat semua orang, Anda dapat menggunakan titik koma untuk memisahkan pernyataan. Anda tidak harus melakukannya, dan itu bukan gaya yang biasa.

Adapun mengapa ini berguna, beberapa orang suka menempatkan dua atau lebih pernyataan pendek yang benar-benar sepele pada satu baris (secara pribadi saya pikir ini mengubah beberapa sepele garis skim dengan mudah menjadi satu garis yang terlihat rumit dan membuatnya lebih sulit untuk melihat bahwa itu sepele) .

Tapi itu hampir merupakan persyaratan ketika Anda menggunakan Python one liners dari shell menggunakan python -c '<some python code>'. Di sini Anda tidak dapat menggunakan lekukan untuk memisahkan pernyataan, jadi jika one-liner Anda benar-benar dua-liner, Anda harus menggunakan titik koma. Dan jika Anda ingin menggunakan argumen lain dalam one-liner Anda, Anda harus mengimpor sysuntuk mendapatkannya sys.argv, yang memerlukan importpernyataan terpisah . misalnya

python -c "import sys; print ' '.join(sorted(sys.argv[1:]))" 5 2 3 1 4
1 2 3 4 5
Ben
sumber
2
Anda dapat menggunakan lekukan dan baris baru saat melewati perintah pythondi dalam shell: Cukup rentang kode yang Anda kutip di beberapa baris atau gunakan heredoc. Namun, itu gagal jika Anda ingin menjadi "satu-liner". ;)
00dani
termasuk ciri untuk jawaban rel dengan-c
n611x007
6

Saya menyadari bahwa saya bias sebagai programmer C lama, tetapi ada kalanya berbagai konvensi Python membuat hal-hal sulit untuk diikuti. Saya menemukan konvensi indentasi sedikit gangguan di kali.

Terkadang, kejelasan kapan pernyataan atau blok berakhir sangat berguna. Kode C standar akan sering membaca sesuatu seperti ini:

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

continue doing things;

di mana Anda menggunakan spasi putih untuk banyak kejelasan - dan mudah untuk melihat di mana loop berakhir.

Python membiarkan Anda mengakhiri dengan titik koma (opsional). Seperti disebutkan di atas, itu TIDAK berarti bahwa ada pernyataan untuk dieksekusi diikuti oleh pernyataan 'nol'. SO, misalnya,

print(x);
print(y);

Sama dengan

print(x)
print(y)

Jika Anda yakin bahwa yang pertama memiliki pernyataan nol di akhir setiap baris, coba - seperti yang disarankan - lakukan ini:

print(x);;

Ini akan menimbulkan kesalahan sintaksis.

Secara pribadi, saya menemukan titik koma untuk membuat kode lebih mudah dibaca ketika Anda memiliki banyak fungsi bersarang dan dengan banyak argumen dan / atau arg panjang. Jadi, bagi saya, ini jauh lebih jelas daripada pilihan lain:

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

karena, bagi saya, ini memberi tahu Anda bahwa ')' terakhir mengakhiri 'blok' yang melewati banyak baris.

Saya pribadi berpikir ada banyak yang harus dibuat dari pedoman gaya PEP, IDE yang menegakkannya, dan kepercayaan ada 'hanya satu cara Pythonic untuk melakukan sesuatu'. Jika Anda percaya yang terakhir, lihat bagaimana memformat angka: seperti yang sekarang, Python mendukung empat cara berbeda untuk melakukannya.

Saya yakin saya akan dinyalakan oleh beberapa diehard, tetapi kompiler / penerjemah tidak peduli jika argumen memiliki nama panjang atau pendek, dan - tetapi untuk konvensi indentasi dengan Python - tidak peduli dengan spasi putih. Masalah terbesar dengan kode adalah memberikan kejelasan kepada manusia lain (dan bahkan diri Anda sendiri setelah berbulan-bulan bekerja) untuk memahami apa yang terjadi, di mana segala sesuatu mulai dan berakhir, dll.

eSurfsnake
sumber
5

Kutipan dari " When Pythons Attack "

Jangan mengakhiri semua pernyataan Anda dengan titik koma. Secara teknis legal untuk melakukan ini dengan Python, tetapi sama sekali tidak berguna kecuali jika Anda menempatkan lebih dari satu pernyataan pada satu baris (misalnya, x = 1; y = 2; z = 3).

Komunis
sumber
4
Mengapa tidak x,y,z = 1,2,3?
Anirban Nag 'tintinmj'
5
@ AnirbanNag'tintinmj 'Dalam kasus khusus ini, saya percaya x, y, z = 1, 2, 3lebih lambat karena menimbulkan perjalanan bolak-balik yang tidak perlu untuk membangun sebuah tuple dan kemudian segera menguraikannya. (Ngomong-ngomong, saya tidak benar-benar berpikir @communistpancake menyarankan x=1; y=2; z=3polanya. Saya pikir dia hanya memberikan contoh bagaimana titik koma adalah pemisah dan bukan terminator.)
RayLuo
1
@AnirbanNag - karena itu akan menjadi contoh sampah dari baris multi-pernyataan.
cz
4

Beberapa pernyataan pada satu baris dapat menyertakan titik koma sebagai pemisah. Sebagai contoh: http://docs.python.org/reference/compound_stmts.html Dalam kasus Anda, ini memudahkan penyisipan titik untuk masuk ke debugger.

Juga, sebagaimana disebutkan oleh Mark Lutz dalam Learning Python Book , secara teknis legal (walaupun tidak perlu dan menjengkelkan) untuk mengakhiri semua pernyataan Anda dengan titik koma.

mandarg
sumber
2

Python tidak membiarkan Anda menggunakan titik koma untuk menunjukkan akhir dari sebuah pernyataan jika Anda memasukkan lebih dari satu pernyataan pada sebuah baris.

Godwin
sumber
2

Titik koma dapat digunakan untuk satu baris dua atau lebih perintah. Mereka tidak harus digunakan, tetapi mereka tidak dibatasi.

Tanda titik koma (;) memungkinkan banyak pernyataan pada baris tunggal mengingat tidak ada pernyataan yang memulai blok kode baru.

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

tempurung kepala
sumber
2

Titik koma (seperti titik, koma, dan kurung) cenderung menyebabkan perang agama. Namun, mereka (atau simbol serupa) berguna dalam bahasa pemrograman apa pun karena berbagai alasan.

  • Praktis: kemampuan untuk menempatkan beberapa perintah pendek yang secara konseptual dimiliki bersama pada baris yang sama. Teks program yang terlihat seperti ular sempit memiliki efek sebaliknya dari apa yang dimaksudkan oleh baris baru dan lekukan, yang menyoroti struktur.

  • Konseptual: pemisahan kekhawatiran antara sintaksis murni (dalam hal ini, untuk urutan perintah) dari presentasi (misalnya baris baru), di masa lalu disebut "pencetakan cantik".

Pengamatan: untuk menyoroti struktur, lekukan dapat ditambah / diganti dengan garis-garis vertikal dengan cara yang jelas, berfungsi sebagai "penguasa visual" untuk melihat di mana lekukan dimulai dan berakhir. Warna yang berbeda (misalnya mengikuti kode warna untuk resistor) dapat mengkompensasi crowding.

Raymond
sumber
1

Itu diizinkan karena penulis memutuskan untuk mengizinkannya: https://docs.python.org/2/reference/simple_stmts.html

Jika pindah ke pertanyaan mengapa penulis memutuskan untuk melakukannya, saya kira itu karena semi-kolom diperbolehkan sebagai penghentian pernyataan sederhana setidaknya dalam bahasa berikut: C ++, C, C #, R, Matlab, Perl, ...

Jadi lebih cepat untuk beralih ke penggunaan Python untuk orang-orang dengan latar belakang dalam bahasa lain. Dan tidak ada kehilangan generalitas dalam deicison tersebut.

bruziuz
sumber
1

Titik koma (";") hanya diperlukan untuk pemisahan pernyataan dalam blok yang sama, seperti jika kita memiliki kode C berikut:

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

Itu dapat ditulis dalam Python dalam salah satu dari dua bentuk:

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

Atau

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

Dalam contoh di atas, Anda dapat memiliki sejumlah pernyataan dalam satu ifblok dan dapat dipisahkan dengan ";" sebagai gantinya.

Semoga tidak ada yang sesederhana penjelasan di atas.

Mohd Asim
sumber
0

Menambah pengetahuan luas yang ada di sini,
Ini adalah jawaban yang terkait dengan perpustakaan 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')

Jika Anda tidak memberikan tanda titik koma di akhir barh (bilah horizontal), hasilnya adalah plot + alamat fungsi. Tetapi jika Anda menggunakan titik koma di akhir kedua baris barh, maka itu hanya menunjukkan plot dan menekan output untuk alamat fungsi.

Sesuatu seperti ini: Perbandingan

Farhan Khan
sumber
3
Ini khusus untuk IPython, dan tidak berlaku untuk REPL Python standar.
wjandrea
Saya pikir ini adalah contoh cemerlang di mana cara penulis bahasa berpikir mereka memperkenalkan kesederhanaan, kekuatan, dan keseragaman gagal berpikir ke depan untuk masalah seperti ini.
eSurfsnake