Mengapa tidak ada pengubah akses eksplisit di Python:

28

Jika 'eksplisit lebih baik daripada implisit', mengapa tidak ada pengubah akses eksplisit di Python: Publik, Terlindungi, Pribadi, dll.?

Saya tahu bahwa idenya adalah programmer harus tahu apa yang harus dilakukan melalui petunjuk - tidak perlu menggunakan 'brute force'. Tetapi 'Enkapsulasi' atau 'penyembunyian informasi' IMO tidak hanya untuk mengusir orang, ini adalah masalah organisasi dan struktur: lapisan pengembangan Anda harus memiliki lingkup dan batas yang jelas dan dibatasi sendiri, seperti halnya sistem fisik.

Dapatkah seseorang tolong bantu saya di sini dengan penjelasan yang kuat tentang mengapa pembatasan akses tersirat daripada eksplisit dalam Python, sebuah bahasa yang tampaknya dekat dengan sempurna?

Sunting: Sejauh ini saya telah melihat 3 jawaban yang diajukan, dan saya menyadari bahwa ada 2 bagian dari pertanyaan saya:

  1. Mengapa tidak ada kata kunci, misalnya

    private def myFunc(): 
        dostuff....
    

    bukannya IMO garis bawah jelek dan sulit untuk mengetik. Tapi itu bukan poin penting.

  2. Lebih penting:

    Mengapa pengubah akses ini hanya 'rekomendasi' atau petunjuk dan tidak ditegakkan. Akan sulit untuk mengubahnya nanti? Sangat mudah untuk mengubah 'dilindungi' menjadi 'publik' - dan jika Anda memiliki rantai pewarisan yang berbelit-belit yang menyulitkan, Anda memiliki desain yang buruk - desain Anda harus disempurnakan daripada mengandalkan fitur bahasa yang membuatnya mudah untuk ditulis kode terstruktur dengan buruk.

    Ketika pengubah akses diberlakukan, kode Anda secara otomatis akan dikotak-kotakkan - Anda TAHU bahwa segmen-segmen tertentu berada di luar jangkauan sehingga Anda tidak perlu menghadapinya kecuali jika dan ketika diperlukan. Dan, jika desain Anda tidak bagus dan Anda menemukan diri Anda terus-menerus memindahkan barang ke dalam dan keluar dari lingkup yang berbeda, bahasa tersebut dapat membantu Anda untuk membersihkan tindakan Anda.

Seperti saya mencintai Python, saya menemukan poin ke-2 ini menjadi kekurangan serius. Dan saya belum melihat jawaban yang bagus untuk ini.

Vektor
sumber
kemungkinan duplikat penentu akses dengan Python: ... yang ditutup tidak konstruktif.
Frank Shearar
2
@Jujur ini adalah pertanyaan ulang dari pertanyaan itu untuk mencoba menjadi lebih konstruktif. Saya telah melanjutkan dan menghapus pertanyaan awal.
@ Mark Trapp: Ah OKE. Terimakasih atas klarifikasinya. Saya tidak bisa melihat cara membatalkan suara saya untuk ditutup.
Frank Shearar
@ Frank Ini akan menua dengan sendirinya.
Adam Lear
masalahnya private def whateveradalah, itu class x: def whatever(self): passadalah jalan pintas untuk class x: pass; x.whatever = lambda self: pass, jadi pada dasarnya, Anda akan memerlukan modifikator pribadi untuk penugasan
keppla

Jawaban:

22

"Eksplisit lebih baik daripada implisit" hanyalah salah satu pepatah dalam filosofi desain Python. "Sederhana lebih baik daripada kompleks" juga ada di sana. Dan, meskipun tidak ada dalam Zen Python, "Kita semua menyetujui orang dewasa di sini" adalah hal lain.

Aturan kedua itu mungkin yang paling penting di sini. Ketika saya mendesain sebuah kelas, saya punya ide tentang bagaimana itu akan digunakan. Tapi saya tidak bisa memprediksi semua kegunaan yang mungkin. Ini mungkin bahwa beberapa penggunaan masa depan kode saya membutuhkan akses ke variabel Aku sudah memikirkan sebagai pribadi. Mengapa saya harus membuatnya sulit - atau bahkan tidak mungkin - untuk mengakses ini, jika seorang programmer masa depan (atau bahkan masa depan saya) membutuhkannya? Hal terbaik yang harus dilakukan adalah menandai mereka dengan peringatan - seperti dicatat Joonas, satu awalan garis bawah adalah standar - bahwa mereka internal, dan mungkin berubah; tetapi melarang akses sama sekali sepertinya tidak perlu.

Daniel Roseman
sumber
1
"Sederhana lebih baik daripada kompleks" dan "Kita semua menyetujui orang dewasa di sini" adalah alasan mengapa Smalltalk tidak memiliki pengubah akses. Menempatkan metode dalam kategori "pribadi" adalah petunjuk bahwa Anda harus berpikir tiga kali sebelum menggunakannya, dan tidak lebih.
Frank Shearar
@ Frank: "Menempatkan metode dalam kategori" pribadi "adalah petunjuk bahwa Anda harus berpikir tiga kali sebelum menggunakannya, dan tidak lebih" Bagi saya, itu berarti saya tidak perlu khawatir tentang hal itu ketika saya tidak berurusan dengan itu.
Vektor
8
Ada alasan bagus mengapa melarang akses ke anggota pribadi: karena itu dapat merusak invarian kelas. Jika Anda tidak dapat menulis anggota pribadi, maka Anda tidak dapat memastikan kelas Anda berperilaku dengan benar.
svick
7
"Mengapa saya harus mempersulit - atau bahkan tidak mungkin - untuk mengakses ini, jika seorang programmer masa depan (atau bahkan masa depan saya) membutuhkannya?" Karena salah satu prinsip dasar desain adalah pemisahan antara antarmuka (apa yang disediakan oleh kode) dan implementasi (bagaimana ia menyediakannya). Enkapsulasi berfungsi untuk mengurangi kompleksitas kode dengan mengurangi ketergantungan antara berbagai bagian kode. Jadi, publik dan pribadi digunakan tepat untuk tujuan menjaga kode lebih sederhana dengan membiarkan hanya melihat apa yang dibutuhkan.
Giorgio
3
Tidak bisa setuju lagi. Access modifiers mempromosikan dua konsep yang mungkin paling dipahami untuk mengurangi kompleksitas dalam perangkat lunak besar: Enkapsulasi dan Pemisahan Masalah. Gagal melayani keduanya tidak berarti python bukan bahasa OOP yang baik atau cocok untuk membangun perangkat lunak besar dan tidak ada yang salah dengan itu. Tapi membenarkan tidak adanya fitur seperti itu dengan argumen hobi khas seperti "Mengapa menambah kompleksitas ketika itu tidak diperlukan?" hanya salah.
Daniel Shin
10

Saya menduga alasan utama untuk pengubah akses yang hilang adalah Kesederhanaan

Seperti yang Anda katakan, ini bukan tentang mengusir orang, ini tentang organisasi, jadi poin utama 'pribadi' adalah, bahwa ia mengirim pesan ke pengguna api Anda 'tolong jangan menulis kode yang tergantung pada ini'.

Sepele untuk mengatakan 'dengan konvensi, _x atau __x tidak boleh digunakan di luar kelas', tetapi dalam model objek dinamis python, bahkan akan sulit untuk menghasilkan notasi.

class ActiveRow(object):
    def __init__(self, **kwargs):
        for name, value in kwargs.items():
            setattr(self, name, value)

bagaimana cara mencatat aksesibilitas?

Saya kira, ini adalah trade off. Jika Anda benar-benar tidak bisa hidup dengan itu, saya akan menyarankan ruby, yang memiliki tingkat abstraksi dan dinamika yang serupa, tetapi memiliki model objek, yang memungkinkan untuk modifikasi akses.

keppla
sumber
8
Saya pikir ini benar, tetapi IMO, itu mengerikan. Untuk bahasa yang menggunakan keanggunan dan keterbacaan sebagai nilai jual, menulis __method__ cukup mengerikan dan tumpul.
jiggy
2
itu bukan konvensi, __x__adalah 'sihir', (yaitu metode yang dipanggil untuk memungkinkan integrasi bahasa seperti kelebihan operator, iterabilitas, dll.). Konvensi tersebut adalah _x.
keppla
6
Maaf, saya masih mendapatkan kepala saya di sekitar Python. Saya berusaha sangat keras untuk menyukainya, tetapi hal-hal seperti ini membuat saya sedikit kesal. Apalagi sekarang saya perlu mengingat arti dari berapa banyak garis bawah yang dimiliki suatu metode. Untuk poin OP, tampaknya pengubah eksplisit akan lebih jelas. Kesepakatan itu bagus, tetapi itu tidak bisa mengalahkan kejelasan. Anda menghabiskan upaya 10X lebih banyak mempertahankan kode daripada membangunnya.
jiggy
2
Contoh saya tidak dimaksudkan untuk menunjukkan jumlah garis bawah yang berbeda, penggunaannya __init__bersifat insidental. Contoh ini menetapkan beberapa properti objek, yang tidak diketahui pada waktu kompilasi, jadi pengubah akses eksplisit tidak akan membantu Anda.
keppla
5
@ jiggy: "Saya berusaha keras untuk menyukainya". Saya mencoba selama 2 tahun - kemudian menyerah. :) mempertahankan kode daripada membangunnya '. OOP sederhana dan mengetik konsep yang aman membutuhkan peretasan dan penyelesaian yang gila.
Vektor
8

Konvensi Python adalah menggunakan awalan garis bawah untuk anggota yang dilindungi / pribadi.

Konvensi ini, jika diikuti, secara efektif sama dengan pengubah akses, kecuali 1) Anda akan melihat langsung dari anggota ini nama apakah itu umum atau tidak, dan 2) Anda dapat mematahkan "enkapsulasi" jika Anda benar-benar ingin (ini bisa dibenarkan dalam pengujian misalnya; dalam beberapa bahasa lain Anda harus menggunakan refleksi == lebih banyak kode).

Pada akhirnya ini adalah masalah selera, tetapi jika Anda dapat melakukan hal yang sama (dengan sedikit lebih banyak fleksibilitas) tanpa kata kunci khusus, bahasanya akan lebih kecil dan kode akan lebih ringkas, yang umumnya merupakan hal yang baik.

Joonas Pulakka
sumber
2
"jika Anda dapat melakukan hal yang sama (dengan sedikit lebih banyak fleksibilitas) tanpa kata kunci khusus, bahasa akan lebih kecil dan kode akan lebih ringkas" Menurut saya, ini umumnya tidak benar. (Bahkan jika itu bisa benar dengan kasus khusus pengubah akses)
BenjaminB