mengapa fungsi kosong diperlukan

9

Saya mulai belajar python dan saya bertanya-tanya mengapa fungsi kosong diperlukan dalam bahasa pemrograman

misalnya dengan python:

def empty_func():
    pass

bahkan dalam skrip shell fungsi kosong fungsi kosong tersedia.

Pemahaman dan pertanyaan saya:

  1. Mengapa bahasa pemrograman membutuhkan fungsi kosong? Apakah hanya bermain-main dengan bahasa pemrograman atau tidak ada hal lain yang benar-benar penting?

  2. Jika ini memiliki tujuan, adakah yang bisa menggambarkan use case atau memberikan contoh nyata penggunaan fungsi kosong?

  3. Atau adakah tradisi bahasa pemrograman yang memungkinkan fungsi kosong?


EDIT (Hal yang saya dapat dari membaca jawaban Anda):

  • Untuk Sketsa Algoritma atau dengan Fungsi Abstrak
  • Untuk mengirimkan formulir tanpa tindakan perlu dilakukan
  • Placeholder untuk beberapa operasi wajib
jeyanthinath
sumber
1
mereka dapat digunakan sebagai STUBS jika eksekusi program mengharapkan untuk menemukan / menggunakannya, namun Anda tidak ingin mengubah apa pun melalui mereka.
G.Rassovsky

Jawaban:

5

Dalam bahasa shell dari keluarga Bourne, :perintah, yang tidak melakukan apa-apa, biasanya digunakan dalam dua situasi:

  • Placeholder untuk saat sesuatu mengharapkan perintah wajib, misalnya

    while some_condtion
    do :
    done

    karena domemerlukan setidaknya satu perintah.

  • Membuang argumen, tetapi melakukan efek samping di dalam daftar argumen, misalnya

    : ${myvar=foo}

Saya yakin mungkin ada aplikasi lain yang ahli shell akan tahu :)

Dalam Python (dan bahasa lain) itu lebih jarang digunakan. Ini dapat bertindak sebagai argumen untuk fungsi tingkat tinggi ketika Anda tidak benar-benar ingin melakukan apa pun. Misalnya, Anda memiliki fungsi yang mengirimkan formulir dan memungkinkan fungsi dipanggil secara tidak sinkron setelah pengiriman selesai:

def submit(callback=empty_func):
    ...

Dengan cara ini, jika callbacktidak disediakan, pengajuan akan tetap melalui tetapi tidak ada tindakan lebih lanjut akan dilakukan. Jika Anda telah menggunakan Nonesebagai nilai default, Anda harus secara eksplisit memeriksa apakah panggilan balik itu None, menambahkan kekacauan pada kode.

Rufflewind
sumber
1

Itu tergantung pada di mana Anda berada dalam siklus pengembangan, tetapi kadang-kadang ketika membuat sketsa algoritma, Anda ingin membuat abstraksi tentang blok kompleks tanpa langsung mengimplementasikannya.

def full_algo():
  init_stuff()
  process_stuff()
  ...

Anda tahu bagaimana cara init_stuffkerjanya, itu agak sederhana di kepala Anda tetapi Anda tidak benar-benar membutuhkannya segera, sehingga Anda mendeklarasikannya sebagai fungsi kosong. Ini akan memungkinkan kode Anda untuk dikompilasi dan dijalankan tanpa peduli tentang detail berdarah.

Penggunaan lain untuk aplikasi yang dirilis adalah ketika menggunakan warisan. Misalkan Anda memiliki kelas besar yang mendefinisikan perilaku kode spesifik platform. Anda mungkin berakhir dengan logika yang mirip dengan ini:

init_filesystem();
access_files();
release_filesystem();

Kode ini akan berfungsi pada banyak platform, tetapi beberapa platform mungkin tidak memerlukan inisialisasi sistem file. Maka warisan Anda akan terlihat seperti ini (virtual dengan = 0 di C ++ hanya berarti bahwa kelas turunan HARUS mengimplementasikan metode tersebut):

class FileSystem{
  virtual void init_filesystem() = 0;
  virtual void access_files() = 0;
  virtual void release_filesystem() = 0;
};

Maka implementasi tertentu dari kelas ini (antarmuka) mungkin tidak melakukan apa pun untuk beberapa metode tersebut. Atau, kelas dasar dapat mendeklarasikan metode kosong untuk init / release daripada mendeklarasikannya secara virtual.

Akhirnya (dan memalukan), terkadang Anda memelihara aplikasi yang sangat lama. Anda takut bahwa menghapus metode akan merusak banyak hal. Ini terjadi ketika Anda memiliki warisan kompleks yang tidak dipahami dengan benar atau ketika Anda memiliki banyak fungsi pointer (panggilan balik). Anda cukup menghapus kode di dalamnya sehingga mereka dipanggil tetap tanpa merusak apa pun.

Eric
sumber
0

Rufflewind melakukan pekerjaan dengan baik saat Anda dapat menggunakan fungsi kosong di program yang sudah selesai. Dalam pengalaman saya, itu cenderung lebih sering digunakan dalam program yang belum selesai, sehingga Anda dapat merencanakan apa yang akan Anda tulis dan masih mengkompilasi sampai Anda benar-benar mengimplementasikannya. Dengan kata lain, biasanya hanya tempat penampung.

Ini diperlukan dalam kasus python karena menggunakan lekukan untuk menandai blok, tidak seperti bahasa mirip C yang menggunakan kawat gigi {}. Ini berarti jika Anda tidak memilikinya pass, parser tidak dapat menentukan apakah Anda bermaksud membiarkannya kosong atau jika Anda lupa. Termasuk passmembuat parser lebih sederhana, dan memberi Anda kata yang mudah untuk dicari ketika Anda sedang mencari blok yang tidak diterapkan.

Karl Bielefeldt
sumber
1
Untuk kode yang belum selesai, melempar NotImplementedErroradalah solusi yang lebih memadai karena "Kesalahan seharusnya tidak pernah diam-diam" dan memanggil fungsi yang tidak diimplementasikan dalam program langsung adalah kesalahan.
ivan_pozdeev
Itu tergantung. Untuk kode yang Anda kirim, ya. Tetapi jika itu adalah kode yang Anda harapkan untuk diimplementasikan dalam satu jam dan Anda hanya membiarkannya tidak diimplementasikan saat Anda mengerjakan tes unit, hanya meninggalkan tidak ada implementasi mungkin merupakan pilihan yang lebih baik. Seringkali alur kerja saya adalah 1) menulis metode rintisan dengan pass 2) menulis unit test yang menguji nilai kembali 3) memverifikasi tes gagal (sebagai metode mengembalikan tidak terdefinisi) 4) menerapkan metode 5) memverifikasi tes sekarang berlalu
Gort the Robot
0

Meskipun ini bukan sesuatu yang Anda harapkan untuk dilakukan dengan Python, ada saat-saat di dunia driver perangkat di mana Anda perlu menyediakan fungsi kosong, untuk menangani peristiwa yang Anda (a) tahu tidak akan terjadi atau ( b) tidak peduli bahkan jika itu terjadi.

Anda juga melihat ini dalam C dengan panggilan balik. Kadang-kadang, Anda akan melihat kode yang hanya MENANGGUNG Anda memberikan panggilan balik, dan mencoba menyebutnya, mengabaikan risiko penunjuk nol. Yang dapat Anda lakukan dalam hal ini adalah menyediakan rutinitas panggilan balik kosong. (Ya, saya memiliki vendor tertentu dalam pikiran.)

John R. Strohm
sumber
Saya passbanyak menggunakan sebagai pengganti ketika menulis kode, terutama di kelas, ketika saya ingin sesuatu yang bisa dijalankan sebelum semuanya selesai. Ini benar-benar setara dengan python {}, yang tidak dapat dilakukan oleh python karena tidak menggunakan kawat gigi. Dalam pengertian itu, semua bahasa yang saya ketahui mengizinkan hal ini, hanya saja beberapa orang seperti pythonmemerlukan kata kunci. Bahkan di hari-hari kebaktian yang kita miliki NOP.
Gort the Robot
@StevenBurnap, biasanya ketika saya melakukan sesuatu seperti itu, saya menyertakan setara lokal printf (">>> XXX rutin bernama \ n");
John R. Strohm