Dalam tugas pekerjaan rumah baru-baru ini saya akhirnya memanggil fungsi saya dengan cara yang buruk uglyReceipt(cashParser(cashInput()))
program itu sendiri bekerja dengan sempurna tetapi saya masih merasa seperti saya melakukan sesuatu yang salah.
Apakah memanggil fungsi seperti praktik buruk ini dan jika demikian: Apa yang harus saya lakukan?
python
coding-style
code-quality
python-3.x
Carl groth
sumber
sumber
Jawaban:
Ini sangat tergantung pada seberapa banyak sarang yang Anda gunakan. Bagaimanapun, Anda diizinkan untuk menggunakan hasil fungsi secara langsung dalam ekspresi untuk meningkatkan keterbacaan. Keduanya, kode yang tidak menggunakan ekspresi tersarang (seperti kode assembler), dan kode yang menggunakan terlalu banyak ekspresi tersarang sulit dibaca. Kode yang baik mencoba untuk mencapai keseimbangan di antara yang ekstrem.
Jadi mari kita lihat beberapa contoh. Yang Anda berikan dalam pertanyaan Anda tampaknya cukup sah bagi saya, jadi tidak perlu khawatir di sini. Namun, garis seperti
pasti tidak akan ditoleransi. Demikian juga, kode suka
tidak akan terlalu mudah dibaca.
sqrt(x*x + y*y + z*z)
jauh lebih mudah dipahami, meskipun menggabungkan total enam operasi berbeda dalam satu ekspresi.Saran saya adalah perhatikan ekspresi apa yang masih bisa Anda uraikan dengan mudah. Saat Anda perlu melihat kedua untuk memahami apa yang dilakukan ekspresi tunggal, sekarang saatnya untuk memperkenalkan variabel tambahan.
sumber
Saya pikir apakah itu baik atau buruk tergantung banyak pada konteksnya. Alasan utama itu mungkin dianggap buruk adalah bahwa hal itu (bisa dibilang) membuat kode lebih sulit untuk dibaca dan di-debug. Ini terutama benar ketika Anda pertama kali belajar memprogram. Saat keterampilan pengkodean (dan kode) Anda semakin maju, ada saatnya hal ini dapat diterima.
Misalnya, pertimbangkan pesan kesalahan seperti ini:
Bagaimana Anda tahu jika argumen yang hilang adalah untuk
cashInput
,cashParser
atauuglyReceipt
? Tergantung pada bahasa pesan kesalahan mungkin memberitahu Anda, tetapi mungkin tidak.Jika Anda ingin memecah panggilan fungsi tersebut, dan pesan kesalahan masih mengarahkan Anda ke saluran 1492, Anda akan langsung tahu di mana letak masalahnya:
Dengan langkah-langkah yang dipisah secara terpisah, jauh lebih mudah untuk debug karena dimungkinkan untuk menetapkan breakpoint pada langkah apa pun, dan Anda dapat dengan mudah menyuntikkan nilai dengan mengubah nilai variabel lokal.
sumber
Konsep yang mendasari pertanyaan Anda sangat penting sehingga saya merasa perlu jawaban lain daripada hanya komentar (seperti yang sudah mulai saya lakukan).
3 jawaban lainnya sejauh ini memberikan beberapa poin pertimbangan yang berguna tentang apakah situasi tertentu pantas menggunakan apa yang Anda sebut "panggilan fungsi bersarang". Tapi mungkin poin yang lebih penting disembunyikan dalam komentar di bawah pertanyaan Anda: jika Anda melewatkan kehalusan dalam apa yang orang-orang terpelajar menyarankan, Carl, Anda telah menemukan sendiri topik yang sebenarnya disebut pemrograman fungsional . Jika Anda belum pernah melihat istilah tersebut, Anda mungkin tidak berpikir itu benar-benar "hal" dalam komentar @ HighPerformanceMark.
Tapi memang benar! Pemrograman fungsional telah ditulis selama puluhan tahun, sejak makalah seminal John Hughes, Why Functional Programming Matters . Ada beberapa bahasa yang merupakan bahasa fungsional (yaitu mereka hanya membiarkan Anda menulis dalam gaya pemrograman fungsional), bahasa seperti Erlang, Lisp, OCaml, atau Haskell. Tetapi ada banyak lagi bahasa yang merupakan hibrida imperatif / bahasa fungsional. Artinya, mereka secara tradisional adalah bahasa imperatif tetapi menawarkan beberapa dukungan untuk pemrograman fungsional juga, termasuk Perl, C ++, Java, C #, dan banyak lagi. Entri Wikipedia tentang pemrograman fungsional menyediakan bagian yang bagus yang menunjukkan perbandingan gaya fungsional vs gaya imperatif untuk sejumlah bahasa.
Ada banyak yang bisa dikatakan tentang perbedaan antara gaya imperatif dan gaya, tetapi titik awal kuncinya adalah bahwa dengan pemrograman fungsional, fungsi atau metode tidak memiliki efek samping , sehingga secara umum lebih mudah untuk memahami dan men-debug program.
Untuk bacaan lebih lanjut, Anda mungkin juga melihat Reginald Braithwaite's Why "Why Functional Programming Matters" Matters dan pos menarik lainnya di SO, Mengapa bahasa fungsional?
sumber
Ini sama sekali bukan praktik yang buruk secara umum. Fungsi panggilan menerima nilai dan salah satu cara menghasilkan nilai adalah dengan memanggil fungsi lain.
Ketika saya melihat variabel didefinisikan, seperti:
... Saya harus mempertimbangkan bahwa
parsed_value
mungkin digunakan lebih dari sekali dan saya mungkin harus memeriksa apakah ini benar atau tidak (bagaimana jika perubahan saya merusak sesuatu di tempat lain?). Saat Anda mulai menambahkan lebih banyak variabel, pembaca bisa menjadi lebih kompleks untuk melacak semuanya dan bagaimana mereka terkait. Jadi saya lega ketika saya melihat:... karena ruang lingkup / nilai tengah nilai sudah jelas. Sekarang, seperti biasa, memecah ekspresi panjang menjadi pernyataan terpisah mungkin membantu, terutama jika nama variabel dapat memberikan lebih presisi tentang tujuan suatu nilai:
sumber