Mengapa% s lebih baik daripada + untuk gabungan?

88

Saya mengerti bahwa kita harus menggunakan %suntuk menggabungkan string daripada +di Python.

Saya dapat melakukan salah satu dari:

hello = "hello"
world = "world"

print hello + " " + world
print "%s %s" % (hello, world)
print "{} {}".format(hello, world)
print ' '.join([hello, world])

Tetapi mengapa saya harus menggunakan sesuatu selain dari itu +? Lebih cepat menulis rangkaian dengan sederhana +. Kemudian jika Anda melihat string pemformatan, Anda menentukan tipe eg %sdan %ddan itu. Saya mengerti bisa lebih baik untuk eksplisit tentang jenisnya.

Tetapi kemudian saya membaca bahwa menggunakan +untuk penggabungan harus dihindari meskipun lebih mudah untuk mengetik. Apakah ada alasan yang jelas bahwa string harus digabungkan dengan salah satu dari cara-cara lain?

Niklas Rosencrantz
sumber
29
Siapa bilang lebih baik?
yannis
3
%sbukan untuk Rangkaian, itu spesifikasi konversi untuk format string yang berasal dari C printf(3). Ada kasus untuk menggunakan itu atau operator gabungan; yang Anda gunakan harus didasarkan pada penilaian situasi, bukan dogma. Betapa mudahnya menulis kode sama sekali tidak relevan karena Anda hanya akan melakukannya sekali.
Blrfl
Saya telah memfokuskan kembali pertanyaan menjadi hanya python (meskipun saya bukan orang python dan mungkin masih ada gangguan dalam kode). Pastikan bahwa ini adalah pertanyaan yang Anda minta, membuat pembaruan yang sesuai dan mempertimbangkan mengajukan berbeda pertanyaan jika Anda tertarik di C atau Java.
12
Dan sekarang kita memiliki f-string yang unggul ! print(f"{hello} {world}"), memiliki pembacaan konatenasi karena variabel terlihat di mana mereka terjadi dalam string, dan lebih cepat daripada str.format.
Enrico Borba

Jawaban:

88
  1. Keterbacaan. Sintaks string format lebih mudah dibaca, karena memisahkan gaya dari data. Selain itu, dalam Python, %ssintaksis akan secara otomatis memaksa semua strjenis non untuk str; sementara penggabungan hanya bekerja dengan str, dan Anda tidak dapat menyatukan strdengan int.

  2. Performa. Dalam Python strtidak berubah, jadi string kiri dan kanan harus disalin ke string baru untuk setiap pasangan rangkaian. Jika Anda menggabungkan empat string dengan panjang 10, Anda akan menyalin (10 + 10) + ((10 + 10) +10) + (((10 + 10) +10) +10) +10) = 90 karakter, bukan hanya 40 karakter karakter. Dan hal-hal menjadi semakin buruk secara kuadratik ketika jumlah dan ukuran string meningkat. Java mengoptimalkan kasus ini beberapa kali dengan mengubah rangkaian rangkaian untuk digunakan StringBuilder, tetapi CPython tidak.

  3. Untuk beberapa kasus penggunaan, pustaka logging menyediakan API yang menggunakan string format untuk membuat string entri log dengan malas ( logging.info("blah: %s", 4)). Ini bagus untuk meningkatkan kinerja jika pustaka logging memutuskan bahwa entri log saat ini akan dibuang oleh filter log, sehingga tidak perlu memformat string.

Lie Ryan
sumber
31
apakah Anda memiliki sumber ilmiah atau empiris untuk # 1? Karena saya pikir itu jauh lebih mudah dibaca (terutama dengan lebih dari 2 atau tiga argumen)
Lovis
4
@ L.Möller: Saya tidak yakin sumber seperti apa yang Anda harapkan dari apa yang pada akhirnya merupakan pengalaman subyektif (kemudahan membaca), tetapi jika Anda ingin alasan saya: 1)% s membutuhkan 2 karakter tambahan per placeholder vs + membutuhkan minimum 4 (atau 8 jika Anda mengikuti PEP8, 13 jika Anda memaksa), 2)% s tertutup dalam satu string, sehingga lebih mudah untuk menguraikan secara visual, dengan +, Anda memiliki lebih banyak bagian bergerak: string dekat, operator, variabel , operator, string terbuka, 3) pewarnaan sintaks% s memiliki satu warna untuk setiap fungsi: string dan placeholder, dengan + Anda mendapatkan tiga pewarnaan: string, operator, dan pewarnaan variabel.
Lie Ryan
4
@ L.Möller: 4) Saya memiliki opsi untuk meletakkan string format yang lebih panjang dalam variabel atau kamus, jauh dari tempat format perlu dilakukan, 5) string format dapat ditentukan oleh pengguna dari file konfigurasi, argumen perintah, atau basis data , hal yang sama tidak bisa dikatakan dengan penggabungan. Tapi ya, saya juga tidak akan menggunakan% s ketika saya memiliki lebih dari 4-5 hal untuk diinterpolasi, sebagai gantinya saya akan menggunakan varian% (varname) atau "{foo}" format () dalam Python. Saya pikir nama eksplisit meningkatkan keterbacaan untuk string format yang lebih panjang dengan banyak variabel interpolasi.
Lie Ryan
2
Saya tidak tahu apa yang "benar", itu sebabnya saya bertanya apakah Anda memiliki bukti :-). Sangat setuju dengan komentar kedua Anda
Lovis
6
Saya menemukan # 2 sebagai tersangka - apakah Anda memiliki bukti yang terdokumentasi? Saya tidak terlalu akrab dengan Java, tetapi dalam Rangkaian C # lebih cepat dari interpolasi string . Saya sepenuhnya setuju dengan # 1 dan benar-benar bergantung pada itu untuk memutuskan kapan harus menggunakan yang mana, tetapi Anda harus ingat interpolasi membutuhkan sejumlah penguraian string dan kompleksitas di mana penggabungan tidak memerlukan itu.
Jimmy Hoffa
48

Apakah saya satu-satunya yang membaca dari kiri ke kanan?

Bagi saya, menggunakan %situ seperti mendengarkan penutur bahasa Jerman, di mana saya harus menunggu sampai akhir kalimat yang sangat panjang untuk mendengar apa kata kerjanya.

Manakah dari ini yang lebih jelas sekilas?

"your %s is in the %s" % (object, location)

atau

"your " + object + " is in the " + location  
Mawg
sumber
17
Jelas ini subjektif, karena saya menemukan yang pertama lebih mudah dibaca - dan lebih mudah untuk ditulis dan diedit. Yang kedua memadukan teks dengan kode yang mengaburkan keduanya dan menambahkan noise. Misalnya mudah untuk mendapatkan spasi yang salah di detik.
JacquesB
5
@ JacquesB Saya sebenarnya berpikir otak Anda sangat akrab dengan format ini sehingga Anda langsung melompat ke kurung dan mengganti kata-kata secara instan. Secara teknis ini bukan bacaan dari kiri ke kanan, tapi itu tidak masalah. Saya menemukan saya melakukan itu juga, jadi ya, saya lebih mudah dibaca karena saya tahu saya harus berurusan dengan masalah spasi bodoh sebelum dan sesudah kutipan di detik, dan itu sangat lambat untuk dikerjakan.
Nelson
3
Setelah nbeberapa dekade, pikiran saya bekerja seperti itu juga ;-) Tetapi saya masih mendukung jawaban saya, yang kedua lebih jelas dan lebih mudah dibaca, oleh karena itu untuk mempertahankannya. Dan itu menjadi lebih jelas semakin banyak parameter yang Anda miliki. Pada akhirnya, jika itu adalah pertunjukan tunggal, lakukan apa yang Anda kenal dan nyamankan; jika ini merupakan upaya tim, tegakkan konsistensi dan tinjauan kode; orang bisa terbiasa dengan hal itu.
Mawg
4
Yang pertama adalah cara yang lebih mudah dibaca bagi saya karena memiliki lebih sedikit "cacat" di tengah kalimat. Lebih mudah bagi mata saya untuk melirik sampai akhir kemudian otak saya untuk menguraikan tanda kutip, spasi, dan plus tambahan. Tentu saja, sekarang saya lebih memilih Python Format 3,6 string: f"your {object} is in the {location}".
Dustin Wyatt
8
Saya juga merasa lebih sulit untuk membaca dan menulis ketika variabel perlu dikelilingi dengan tanda kutip itu sendiri. "your '" + object + "' is in the '" + location + "'"... Saya bahkan tidak yakin apakah saya mendapatkannya sekarang ...
Dustin Wyatt
12

Contoh mengklarifikasi argumen keterbacaan:

print 'id: ' + id + '; function: ' + function + '; method: ' + method + '; class: ' + class + ' -- total == ' + total

print 'id: %s; function: %s; method: %s; class: %s --total == %s' % \
   (id, function, method, class, total)

(Perhatikan bahwa contoh kedua tidak hanya lebih mudah dibaca tetapi juga lebih mudah diedit, Anda dapat mengubah templat pada satu baris dan daftar variabel di yang lain)

Masalah terpisah adalah bahwa kode% s juga mengkonversi ke string, jika tidak Anda harus menggunakan panggilan str () yang juga kurang dapat dibaca daripada kode% s.

Hujan
sumber
1
Saya tidak setuju dengan pernyataan pertama Anda, tetapi kami dapat setuju untuk berbeda, saya baru saja akan mengirim jawaban di sepanjang baris kedua Anda, sangat
mendukung
6

Penggunaan +sebaiknya tidak dihindari secara umum. Dalam banyak kasus adalah pendekatan yang benar. Menggunakan %satau .join()hanya disukai dalam kasus-kasus tertentu, dan biasanya cukup jelas ketika mereka adalah solusi yang lebih baik.

Dalam contoh Anda, Anda menggabungkan tiga string bersama-sama, dan contoh menggunakan +jelas yang paling sederhana dan paling mudah dibaca, dan karenanya direkomendasikan.

%satau .format()berguna jika Anda ingin menyisipkan string atau nilai di tengah - tengah string yang lebih besar. Contoh:

print "Hello %s, welcome to the computer!" % name

Dalam hal ini menggunakannya %slebih mudah dibaca karena Anda menghindari memotong string pertama menjadi beberapa segmen. Terutama jika Anda menginterpolasi beberapa nilai.

.join() sesuai jika Anda memiliki urutan ukuran variabel string dan / atau Anda ingin menyatukan beberapa string dengan pemisah yang sama.

JacquesB
sumber
2

Karena urutan kata dapat berubah dalam bahasa yang berbeda, formulir dengan %ssangat penting jika Anda ingin mendukung terjemahan string dalam perangkat lunak Anda.

martjno
sumber