Mengapa tanda kurung di print bersifat sukarela di Python 2.7?

98

Dalam Python 2.7, kedua hal berikut akan melakukan hal yang sama

print("Hello, World!") # Prints "Hello, World!"

print "Hello, World!" # Prints "Hello, World!"

Namun berikut ini tidak akan

print("Hello,", "World!") # Prints the tuple: ("Hello,", "World!")

print "Hello,", "World!" # Prints the words "Hello, World!"

Di Python 3.x, tanda kurung on printadalah wajib, pada dasarnya menjadikannya sebuah fungsi, tetapi di 2.7 keduanya akan bekerja dengan hasil yang berbeda. Apa lagi yang harus saya ketahui tentang printPython 2.7?

Hubro
sumber
7
Dalam Python 2.x printsebenarnya pernyataan khusus, bukan fungsi. Ini juga mengapa itu tidak bisa digunakan seperti: lambda x: print xCatatan itu (expr)tidak membuat Tuple (itu menghasilkan expr), tetapi ,tidak.
Saya berasumsi bahwa dukungan untuk print sebagai fungsi dan print sebagai pernyataan adalah untuk menjaga kompatibilitas ke belakang dengan versi python yang lebih lama sambil mendorong orang untuk menggunakan sintaks baru untuk bermigrasi ke python 3.
GWW
11
ps, Untuk mengaktifkan fungsi cetak di 2.7 (dan tidak memiliki perilaku pernyataan cetak), Anda harus melakukan impor di masa mendatang:from __future__ import print_function
Jeff Mercado
Apakah contoh kedua sebenarnya akan mencetak "Halo, Dunia!" (tanpa spasi) atau akan muncul tulisan "Hello, World!" (dengan spasi) seperti pada contoh.
kapad

Jawaban:

106

Dalam Python 2.x printsebenarnya pernyataan khusus dan bukan fungsi *.

Ini juga mengapa tidak bisa digunakan seperti: lambda x: print x

Perhatikan bahwa (expr)tidak membuat Tuple (itu menghasilkan expr), tetapi ,tidak. Ini mungkin menghasilkan kebingungan antara print (x)dan print (x, y)dengan Python 2.7

(1)   # 1 -- no tuple Mister!
(1,)  # (1,)
(1,2) # (1, 2)
1,2   # 1 2 -- no tuple and no parenthesis :) [See below for print caveat.]

Namun, karena printmerupakan sintaks khusus pernyataan / tata bahasa konstruksi di Python 2.x kemudian, tanpa kurung, itu memperlakukan ,'s dengan cara khusus - dan tidak membuat Tuple. Perlakuan khusus terhadap printpernyataan tersebut memungkinkannya untuk bertindak secara berbeda jika ada jejak ,atau tidak.

Selamat membuat kode.


* printPerilaku di Python 2 ini dapat diubah menjadi perilaku Python 3:

from __future__ import print_function
user2357112 mendukung Monica
sumber
3
Terima kasih atas (expr) != tuplepenjelasannya :-)
Hubro
5

Semuanya sangat sederhana dan tidak ada hubungannya dengan kompatibilitas maju atau mundur.

Bentuk umum printpernyataan di semua versi Python sebelum versi 3 adalah:

print expr1, expr2, ... exprn

(Setiap ekspresi pada gilirannya dievaluasi, diubah menjadi string dan ditampilkan dengan spasi di antara ekspresi tersebut.)

Tapi ingat bahwa meletakkan tanda kurung di sekitar ekspresi masih merupakan ekspresi yang sama.

Jadi Anda juga bisa menulis ini sebagai:

print (expr1), (expr2), ... (expr3)

Ini tidak ada hubungannya dengan memanggil suatu fungsi.

Don O'Donnell
sumber
Ini adalah jawaban yang benar-benar tepat, saya juga tidak yakin mengapa itu banyak diremehkan.
Martijn Pieters
Ini bukan tentang print (expr1), (expr2), ... (expr3), ini tentang mengapa print (expr1, expr2, ... , expr3)legal di python 2.x sementara seharusnya tidak sesuai dengan standar 2.x.
vinnief
5

Di sini kami memiliki efek samping yang menarik dalam hal UTF-8.

>> greek = dict( dog="σκύλος", cat="γάτα" )
>> print greek['dog'], greek['cat']
σκύλος γάτα
>> print (greek['dog'], greek['cat'])
('\xcf\x83\xce\xba\xcf\x8d\xce\xbb\xce\xbf\xcf\x82', '\xce\xb3\xce\xac\xcf\x84\xce\xb1')

Cetakan terakhir adalah tupel dengan nilai byte heksadesimal.

Karlo Smid
sumber
7
Saya berasumsi itu karena print mencetak UTF-8 dengan benar, tetapi ketika menerima tupel, seperti cetakan terakhir Anda, itu berjalan reprdi atasnya, pada titik itu mungkin mengkodekan semua string dalam dict ke ASCII.
Hubro
3
@Codemonkey, Anda benar tentang repr . Anda salah tentang ASCII. ASCII adalah pengkodean default untuk Python. Tapi saya punya di awal script Python #encoding=utf-8, linux env LANG=en_US.UTF-8. Jadi encoding repr tidak menggunakan default ASCII, tetapi encoding utf-8.
Karlo Smid
1
Repr menyandikan strdengan string_escapepengkodean khusus . String tersebut sudah dienkode unicode sebagai UTF-8.
tzot
@KarloSmid: Apa yang saya maksud adalah bahwa reprmungkin mengambil langkah-langkah untuk memastikan bahwa teks dapat diwakili oleh ASCII (dengan cara melarikan diri simbol non-ASCII), belum tentu bahwa string adalah dikodekan sebagai ASCII. Saya masih tidak tahu apakah itu sepenuhnya akurat.
Hubro
Semua wadah Python (list, dict, tuple, set) menyertakan isinya sebagai repr()output ketika diubah menjadi string (mereka tidak diimplementasikan __str__, hanya __repr__). Apa yang Anda lihat tidak istimewa bagi UTF-8; the repr()of a string memberi Anda literal string Python yang valid yang aman ASCII.
Martijn Pieters
2

Pada dasarnya di Python sebelum Python 3, print adalah pernyataan khusus yang mencetak semua string jika didapat sebagai argumen. Jadi print "foo","bar"sederhananya berarti "cetak 'foo' diikuti dengan 'bar'". Masalahnya adalah tergoda untuk bertindak seolah-olah print adalah sebuah fungsi, dan tata bahasa Python ambigu tentang itu, karena (a,b)tupel berisi adan btetapi foo(a,b)merupakan panggilan ke fungsi dari dua argumen.

Jadi mereka membuat perubahan yang tidak kompatibel untuk 3 agar program tidak terlalu ambigu dan lebih teratur.

(Sebenarnya, saya pikir 2,7 berperilaku seperti yang dilakukan 2,6 dalam hal ini, tapi saya tidak yakin.)

Charlie Martin
sumber
Tidak, itu tidak "menggoda" untuk menggunakannya sebagai fungsi. :) Namun, itu tidak mungkin untuk menggunakannya sebagai fungsi, jadi Anda tidak bisa melakukan [print x untuk x dalam daftar] misalnya.
Lennart Regebro