Contoh konkret pepatah Python "hanya satu cara untuk melakukannya" [ditutup]

34

Saya belajar Python dan tertarik pada poin berikut dalam PEP 20 The Zen of Python :

Harus ada satu - dan lebih disukai hanya satu - cara yang jelas untuk melakukannya. Meskipun demikian mungkin tidak jelas pada awalnya kecuali Anda orang Belanda.

Adakah yang bisa menawarkan contoh konkret pepatah ini? Saya khususnya tertarik pada kontras dengan bahasa lain seperti Ruby. Bagian dari filosofi desain Ruby (berasal dari Perl, saya pikir?) Adalah bahwa beberapa cara untuk melakukannya adalah A Good Thing. Adakah yang bisa menawarkan beberapa contoh yang menunjukkan pro dan kontra dari setiap pendekatan. Catatan, saya tidak mencari jawaban yang lebih baik (yang mungkin terlalu subjektif untuk dijawab), melainkan perbandingan yang tidak bias dari kedua gaya.

Charles Roper
sumber

Jawaban:

47

Dibandingkan dengan bahasa seperti Perl, Python memiliki sejumlah konstruk kontrol yang terbatas:

  • hanya ifdan tidak unless,
  • hanya foritu mengulangi urutan dan tidak ada foreachatau gaya-C for,
  • hanya whileitu memeriksa suatu kondisi setiap loop dan tidak do-while,
  • hanya if-elifdan tidak switch,
  • hanya ada satu konstruk komentar #, dan untuk setiap baris Anda dapat mengetahui apakah itu dikomentari atau tidak, tanpa melihat baris sebelumnya.

Juga, ada hampir satu cara untuk indentasi sumber Anda; kebanyakan kasus lekukan kreatif secara sintaksis dikecualikan.

Ini membuat penguraian sumber Python lebih mudah bagi manusia.

Ada upaya untuk menjadi minimal namun lengkap dalam tipe bawaan dan pustaka standar.

  • untuk daftar yang dapat diubah, Anda menggunakan satu-satunya listtipe bawaan; itu O (1) untuk sebagian besar operasi, dan Anda tidak perlu memilih implementasi yang tepat,
  • untuk daftar yang tidak berubah, sama-sama, Anda hanya menggunakan tuplejenisnya,
  • untuk peta, Anda menggunakan satu-satunya built-in dictyang sangat efisien dalam banyak kasus, tidak perlu merenungkan implementasi yang akan digunakan.

Python 3 memperluas ini ke integer: tidak peduli seberapa besar integer Anda, Anda menggunakan tipe yang sama dan tidak pernah peduli tentang paksaan.

Python berusaha menghindari gula sintaksis. Tetapi kadang - kadang itu menambahkan gula sintaksis hanya untuk membuat cara yang jelas menjadi jelas. Anda dapat menulis if foo is not Nonealih-alih if not (foo is None)karena 'tidak' adalah huruf khusus. Masih foo is not Nonemudah dibaca, tidak bisa disalahartikan, dan Anda tidak harus berpikir, Anda hanya menulis hal yang sudah jelas.

Tentu saja, sebagian besar hal yang lebih rumit dalam Python dapat dilakukan dengan beberapa cara. Anda dapat menambahkan metode ke kelas dengan deklarasi atau dengan penetapan slot sederhana, Anda dapat meneruskan argumen ke berbagai fungsi dalam sejumlah cara kreatif, dll. Itu hanya karena bagian dalam bahasa sebagian besar diekspos.

Kuncinya adalah bahwa selalu ada satu cara yang dimaksudkan untuk menjadi yang terbaik, yang mencakup semua kasus. Jika ada cara lain, mereka tidak ditambahkan sebagai alternatif yang sama (seperti ifdan unless) tetapi hanya mengekspos kerja batin. Perlahan tapi pasti alternatif semacam itu sudah usang (tidak dihilangkan!) Dengan meningkatkan mekanisme terbaik yang diketahui.

Dekorator membungkus panggilan fungsi AOP. Sebelum 2.6, Anda harus menggunakan __metaclass__anggota sihir untuk mendeklarasikan metaclass kelas; sekarang Anda dapat menggunakan sintaksis dekorator yang sama untuk ini juga. Sebelum ke 3.0 Anda memiliki dua jenis string, byte-oriented dan Unicode, yang dapat Anda campur secara tidak sengaja. Sekarang Anda memiliki satu-satunya Unicode strdan satu-satunya biner-transparan bytes, yang tidak dapat Anda campur tanpa sengaja.

9000
sumber
3
Sama seperti catatan, jangan lupa """komentar (docstrings). Ini membentang beberapa baris.
asthasr
8
Literal dengan kutip tiga hanyalah string, sama dengan yang dikutip tunggal, tetapi dapat menjangkau beberapa baris tanpa keluar dari garis akhir. String literal tepat setelah deklarasi dianggap sebagai string doc, dan itu bukan komentar, itu biasanya dapat diakses sebagai __doc__atribut. Tetapi string adalah area di mana Python pasti menyediakan banyak 'cara yang benar': gunakan kutipan tunggal, ganda, atau tiga kali lipat, secara implisit bergabung dengan literal yang berdekatan, gunakan runtuk literal mentah, dll.
9000
1
Saya pikir komentar @ syrion adalah mengenai "Anda selalu dapat memutuskan apakah sebuah baris dikomentari atau tidak hanya dengan melihatnya", yang tidak benar karena string "" ".
blubb
2
"Ini membuat penguraian sumber Python lebih mudah bagi manusia." <- itu subjektif
jiggy
Bagaimana deklarasi metaclass berubah di 2.7? Tidak dapat menemukan pola dekorator di 2,7 dokumen untuk metaclasses.
Nick T
10

Beberapa contoh lainnya adalah:
len()adalah fungsi alih-alih metode yang ada di setiap urutan; jika Anda membandingkan dengan Java Anda memiliki .length, .size(), .getSize(), dan metode lain untuk menemukan jumlah elemen secara berurutan.

Contoh lain adalah kenyataan bahwa itu .join()adalah stringmetode, bukan metode yang ada di setiap urutan. Anda tidak perlu tahu apakah parameter gabungan adalah daftar, set, pemahaman, atau apa pun, itu akan berfungsi.

Vito De Tullio
sumber
8

Di C ada banyak cara yang mungkin untuk meningkatkan nilai variabel dengan satu:

i++     // Post-increment, returns the number before the increment
++i     // Pre-increment, returns the number after the increment
i += 1 

Setiap akhirnya meningkatkan nilai ioleh 1, tetapi masing-masing sedikit berbeda.

Dengan Python, hanya ada satu cara; tambahkan saja.

i += 1

Dan sementara ada lebih dari satu cara yang valid secara sintaksis untuk melakukan ini (misalnya i = i + 1), Anda melakukan hal yang sama dengan efek samping yang sama.


sumber
1
Saya bukan ahli, tetapi contoh itu tampaknya justru melanggar ide "satu-satunya cara untuk melakukannya". Kami memiliki dua cara untuk melakukannya, tetapi mana yang lebih jelas? Untuk mata saya contoh pertama lebih jelas sedangkan yang kedua sedikit lebih singkat tetapi tidak kurang dapat dibaca atau jelas bagi setiap programmer yang telah berkembang melampaui sangat dasar. Terima kasih atas jawaban Anda - ini adalah makanan yang bagus untuk dipikirkan.
Charles Roper
@Peter (dan @Charles): Sebenarnya, i = i + 1adalah penugasan, bukan kenaikan. Dalam python kenaikan adalah i += 1. Dalam bahasa C-gaya yang Anda dapat menulis i++, ++idan i += 1.
Josh K
2
Tidak yakin dengan komentar "banyak kebingungan" Anda, ketiga contoh C Anda (Anda tidak terjawab i += 1, BTW) menghasilkan hasil yang persis sama. Satu-satunya saat saya melihat orang-orang menjadi bingung adalah ketika mereka menambah atau menambah variabel sebagai bagian dari ekspresi yang lebih besar, dan itu biasanya cepat diperbaiki dengan membaca bagian referensi bahasa yang sesuai. Secara pribadi, saya akan memilih pada fakta bahwa Anda dapat merujuk ke karakter kelima dari string oleh keduanya str[4]atau *(str+4), tapi mungkin itu terlalu mudah ...
TMN
2
@ TMN: beberapa kasus, seperti max(i++, ++i)tidak dapat dengan cepat diperbaiki. C memiliki banyak kasus perilaku "tidak terdefinisi" dan "tergantung pada implementasi", semua untuk alasan yang baik - tetapi masing-masing dapat membuat perangkap.
9000
@ TMN: Belum lagi 4 [str] (valid dalam C, mungkin tidak valid dalam C ++).
Vatine
6

Kemungkinan lain mungkin daftar pemahaman. Dengan Python, Anda bisa melakukan ini:

new_list = []
    for item in list_of_items:
       if item < 10:
           new_list.append(item)

Tetapi cara "jelas" (jika Anda orang Belanda atau lebih akrab dengan Python) melakukan hal ini adalah dengan pemahaman daftar:

new_list = [item for item in list_of_items if item < 10]

Lebih pendek, new_list dibuat dalam satu langkah, itu berjalan lebih cepat saya percaya, dan elegan. Pada sisi negatifnya, orang bisa berpendapat itu terasa kurang eksplisit, tapi saya pikir begitu Anda terbiasa, itu juga eksplisit.

Chelonian
sumber
Untuk lekukan dan kode: tambahkan dengan 4 spasi, maka itu akan menghormati lekukan.
Inca