Python memberikan kita kemampuan untuk membuat metode 'pribadi' dan variabel dalam kelas dengan mengawali garis bawah ganda untuk nama, seperti ini: __myPrivateMethod()
. Bagaimana, kemudian, seseorang dapat menjelaskan hal ini
>>> class MyClass:
... def myPublicMethod(self):
... print 'public method'
... def __myPrivateMethod(self):
... print 'this is private!!'
...
>>> obj = MyClass()
>>> obj.myPublicMethod()
public method
>>> obj.__myPrivateMethod()
Traceback (most recent call last):
File "", line 1, in
AttributeError: MyClass instance has no attribute '__myPrivateMethod'
>>> dir(obj)
['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']
>>> obj._MyClass__myPrivateMethod()
this is private!!
Apa masalahnya ?!
Saya akan menjelaskan ini sedikit untuk mereka yang tidak mengerti.
>>> class MyClass:
... def myPublicMethod(self):
... print 'public method'
... def __myPrivateMethod(self):
... print 'this is private!!'
...
>>> obj = MyClass()
Apa yang saya lakukan di sana adalah membuat kelas dengan metode publik dan metode pribadi dan instantiate.
Selanjutnya, saya sebut metode publiknya.
>>> obj.myPublicMethod()
public method
Selanjutnya, saya mencoba dan memanggil metode privatnya.
>>> obj.__myPrivateMethod()
Traceback (most recent call last):
File "", line 1, in
AttributeError: MyClass instance has no attribute '__myPrivateMethod'
Semuanya terlihat bagus di sini; kami tidak dapat menyebutnya. Ini sebenarnya adalah 'pribadi'. Sebenarnya tidak. Menjalankan dir () pada objek tersebut mengungkapkan metode magis baru yang python buat secara ajaib untuk semua metode 'pribadi' Anda.
>>> dir(obj)
['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']
Nama metode baru ini selalu garis bawah, diikuti oleh nama kelas, diikuti oleh nama metode.
>>> obj._MyClass__myPrivateMethod()
this is private!!
Begitu banyak untuk enkapsulasi, eh?
Bagaimanapun, saya selalu mendengar Python tidak mendukung enkapsulasi, jadi mengapa bahkan mencoba? Apa yang menyebabkannya?
Jawaban:
Perebutan nama digunakan untuk memastikan bahwa subclass tidak sengaja menimpa metode pribadi dan atribut superclasses mereka. Itu tidak dirancang untuk mencegah akses yang disengaja dari luar.
Sebagai contoh:
Tentu saja, itu rusak jika dua kelas berbeda memiliki nama yang sama.
sumber
Contoh fungsi pribadi
sumber
self = MyClass()
self.private_function()
. : D Tentu saja itu tidak berfungsi di kelas, tetapi Anda hanya perlu mendefinisikan fungsi khusus:def foo(self): self.private_function()
function_call.startswith('self.')
.inspect.stack()[1][4][0].strip()
<- apa angka ajaib 1, 4, dan 0 itu?self = MyClass(); self.private_function()
dan gagal ketika dipanggil menggunakanx = self.private_function()
di dalam metode.Ketika saya pertama kali datang dari Jawa ke Python saya benci ini. Itu membuatku takut sampai mati.
Hari ini mungkin hanya satu hal yang paling saya sukai tentang Python.
Saya suka berada di platform, di mana orang saling mempercayai dan tidak merasa perlu membangun tembok yang tidak bisa ditembus di sekitar kode mereka. Dalam bahasa yang dienkapsulasi dengan kuat, jika API memiliki bug, dan Anda telah menemukan apa yang salah, Anda mungkin masih tidak dapat mengatasinya karena metode yang diperlukan bersifat pribadi. Dalam Python sikapnya adalah: "yakin". Jika Anda pikir Anda memahami situasinya, mungkin Anda bahkan sudah membacanya, maka yang bisa kita katakan adalah "semoga sukses!".
Ingat, enkapsulasi bahkan tidak berhubungan lemah dengan "keamanan", atau menjauhkan anak-anak dari halaman. Ini hanyalah pola lain yang harus digunakan untuk membuat basis kode lebih mudah dimengerti.
sumber
Dari http://www.faqs.org/docs/diveintopython/fileinfo_private.html
sumber
Ungkapan yang umum digunakan adalah "kita semua menyetujui orang dewasa di sini". Dengan menambahkan satu garis bawah (jangan tampilkan) atau garis bawah dua (sembunyikan), Anda memberi tahu pengguna kelas Anda bahwa Anda bermaksud anggota untuk 'pribadi' dengan cara tertentu. Namun, Anda memercayai orang lain untuk berperilaku secara bertanggung jawab dan menghargai itu, kecuali mereka memiliki alasan kuat untuk tidak melakukannya (mis. Debugger, penyelesaian kode).
Jika Anda benar-benar harus memiliki sesuatu yang bersifat pribadi, maka Anda dapat mengimplementasikannya dalam ekstensi (misalnya dalam C untuk CPython). Namun, dalam kebanyakan kasus, Anda hanya mempelajari cara Pythonic dalam melakukan sesuatu.
sumber
Ini tidak seperti Anda absolutly dan tidak dapat menyiasati privasi anggota dalam bahasa apa pun (aritmatika pointer di C ++, Refleksi dalam .NET / Java).
Intinya adalah Anda mendapatkan kesalahan jika Anda mencoba memanggil metode pribadi secara tidak sengaja. Tetapi jika Anda ingin menembak diri sendiri, lanjutkan dan lakukan.
Sunting: Anda tidak mencoba mengamankan barang-barang Anda dengan OO-enkapsulasi, bukan?
sumber
The
class.__stuff
konvensi penamaan memungkinkan programmer tahu dia tidak dimaksudkan untuk akses__stuff
dari luar. Nama mangling membuatnya tidak mungkin ada orang yang melakukannya secara tidak sengaja.Benar, Anda masih bisa mengatasi ini, bahkan lebih mudah daripada dalam bahasa lain (yang BTW juga membiarkan Anda melakukan ini), tetapi tidak ada programmer Python yang akan melakukan ini jika dia peduli tentang enkapsulasi.
sumber
Perilaku serupa ada ketika nama atribut modul dimulai dengan garis bawah tunggal (misalnya _foo).
Atribut modul yang dinamai demikian tidak akan disalin ke modul impor saat menggunakan
from*
metode ini, misalnya:Namun, ini adalah konvensi dan bukan kendala bahasa. Ini bukan atribut pribadi; mereka dapat dirujuk dan dimanipulasi oleh importir mana pun. Beberapa berpendapat bahwa karena ini, Python tidak dapat mengimplementasikan enkapsulasi yang benar.
sumber
Itu hanya salah satu dari pilihan desain bahasa itu. Pada tingkat tertentu mereka dibenarkan. Mereka membuatnya sehingga Anda harus pergi jauh-jauh dari cara Anda untuk mencoba dan memanggil metode, dan jika Anda benar-benar membutuhkannya, Anda harus memiliki alasan yang cukup bagus!
Kait debugging dan pengujian muncul dalam pikiran sebagai aplikasi yang mungkin, tentu saja digunakan secara bertanggung jawab.
sumber
Dengan Python 3.4 ini adalah perilaku:
https://docs.python.org/3/tutorial/classes.html#tut-private
Meskipun pertanyaannya sudah tua, saya harap cuplikan saya dapat membantu.
sumber
Kekhawatiran yang paling penting tentang metode dan atribut pribadi adalah memberi tahu pengembang untuk tidak menyebutnya di luar kelas dan ini enkapsulasi. orang mungkin salah memahami keamanan dari enkapsulasi. ketika seseorang dengan sengaja menggunakan sintaks seperti itu (di bawah) yang Anda sebutkan, Anda tidak ingin enkapsulasi.
Saya telah bermigrasi dari C # dan pada awalnya itu aneh bagi saya juga, tetapi setelah beberapa saat saya sampai pada gagasan bahwa hanya cara para perancang kode Python berpikir tentang OOP berbeda.
sumber
Seperti yang saya pahami, mereka tidak bisa bersifat pribadi. Bagaimana privasi bisa ditegakkan?
Jawaban yang jelas adalah "anggota pribadi hanya dapat diakses melalui
self
", tetapi itu tidak akan berhasil -self
tidak istimewa dalam Python, itu tidak lebih dari nama yang biasa digunakan untuk parameter pertama dari suatu fungsi.sumber