Jika ragu, biarkan "publik" - maksud saya, jangan menambahkan apa pun untuk mengaburkan nama atribut Anda. Jika Anda memiliki kelas dengan beberapa nilai internal, jangan repot-repot. Alih-alih menulis:
class Stack(object):
def __init__(self):
self.__storage = [] # Too uptight
def push(self, value):
self.__storage.append(value)
tulis ini secara default:
class Stack(object):
def __init__(self):
self.storage = [] # No mangling
def push(self, value):
self.storage.append(value)
Ini pasti cara kontroversial dalam melakukan sesuatu. Pemula Python hanya membencinya dan bahkan beberapa orang Python lama tidak menyukai default ini - tetapi ini adalah default, jadi saya sangat menyarankan Anda untuk mengikutinya, bahkan jika Anda merasa tidak nyaman.
Jika Anda benar - benar ingin mengirim pesan "Can't touch this!" kepada pengguna Anda, cara yang biasa dilakukan adalah mendahului variabel dengan satu garis bawah. Ini hanya konvensi, tetapi orang-orang memahaminya dan berhati-hati saat menangani hal-hal seperti itu:
class Stack(object):
def __init__(self):
self._storage = [] # This is ok but pythonistas use it to be relaxed about it
def push(self, value):
self._storage.append(value)
Ini juga bisa berguna untuk menghindari konflik antara nama properti dan nama atribut:
class Person(object):
def __init__(self, name, age):
self.name = name
self._age = age if age >= 0 else 0
@property
def age(self):
return self._age
@age.setter
def age(self, age):
if age >= 0:
self._age = age
else:
self._age = 0
Bagaimana dengan garis bawah ganda? Nah, sihir garis bawah ganda digunakan terutama untuk menghindari overloading yang tidak disengaja pada metode dan konflik nama dengan atribut superclass . Ini bisa sangat berguna jika Anda menulis kelas yang diharapkan dapat diperpanjang berkali-kali.
Jika Anda ingin menggunakannya untuk tujuan lain, Anda bisa, tetapi ini tidak biasa atau tidak disarankan.
EDIT : Mengapa demikian? Nah, gaya Python yang biasa tidak menekankan pada menjadikan hal-hal pribadi - sebaliknya! Ada banyak alasan untuk itu - kebanyakan dari mereka kontroversial ... Mari kita lihat beberapa di antaranya.
Python memiliki properti
Kebanyakan bahasa OO saat ini menggunakan pendekatan yang berlawanan: apa yang tidak boleh digunakan tidak boleh terlihat, jadi atribut harus privat. Secara teoritis, ini akan menghasilkan kelas yang lebih mudah dikelola, kurang digabungkan, karena tidak ada yang akan mengubah nilai di dalam objek secara sembarangan.
Namun, tidak sesederhana itu. Misalnya, kelas Java memang memiliki banyak atribut dan getter yang hanya mendapatkan nilai dan penyetel yang baru saja menyetel nilainya. Anda perlu, katakanlah, tujuh baris kode untuk mendeklarasikan satu atribut - yang menurut programmer Python sangat rumit. Selain itu, dalam praktiknya, Anda cukup menulis seluruh kode ini untuk mendapatkan satu bidang publik, karena Anda dapat mengubah nilainya menggunakan getter dan setter.
Jadi mengapa harus mengikuti kebijakan private-by-default ini? Jadikan atribut Anda publik secara default. Tentu saja, ini menjadi masalah di Java, karena jika Anda memutuskan untuk menambahkan beberapa validasi ke atribut Anda, Anda harus mengubah semua
person.age = age;
dalam kode Anda untuk, katakanlah,
person.setAge(age);
setAge()
makhluk:
public void setAge(int age) {
if (age >= 0) {
this.age = age;
} else {
this.age = 0;
}
}
Jadi di Java (dan bahasa lain), defaultnya adalah menggunakan getter dan setter, karena mereka dapat mengganggu untuk menulis tetapi dapat menghemat banyak waktu jika Anda berada dalam situasi yang telah saya jelaskan.
Namun, Anda tidak perlu melakukannya dengan Python, karena Python memiliki properti. Jika Anda memiliki kelas ini:
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
dan kemudian Anda memutuskan untuk memvalidasi usia, Anda tidak perlu mengubah person.age = age
potongan kode Anda. Tambahkan saja properti (seperti yang ditunjukkan di bawah)
class Person(object):
def __init__(self, name, age):
self.name = name
self._age = age if age >= 0 else 0
@property
def age(self):
return self._age
@age.setter
def age(self, age):
if age >= 0:
self._age = age
else:
self._age = 0
Jika Anda bisa melakukannya dan masih menggunakannya person.age = age
, mengapa Anda menambahkan bidang pribadi dan pengambil dan penyetel?
(Juga, lihat Python bukan Java dan artikel ini tentang kerugian menggunakan getter dan setter .).
Semuanya tetap terlihat - dan mencoba menyembunyikan hanya memperumit pekerjaan Anda
Bahkan dalam bahasa yang memiliki atribut privat, Anda dapat mengaksesnya melalui semacam pustaka refleksi / introspeksi. Dan orang banyak melakukannya, dalam kerangka kerja dan untuk menyelesaikan kebutuhan mendesak. Masalahnya adalah bahwa perpustakaan introspeksi hanyalah cara yang sulit untuk melakukan apa yang dapat Anda lakukan dengan atribut publik.
Karena Python adalah bahasa yang sangat dinamis, menambahkan beban ini ke kelas Anda akan menjadi kontraproduktif.
Masalahnya tidak mungkin untuk dilihat - itu harus dilihat
Untuk Pythonista, enkapsulasi bukanlah ketidakmampuan melihat internal kelas, tetapi kemungkinan untuk menghindari melihatnya. Yang saya maksud adalah, enkapsulasi adalah properti dari komponen yang memungkinkannya digunakan tanpa pengguna khawatir tentang detail internal. Jika Anda dapat menggunakan sebuah komponen tanpa mengganggu diri Anda sendiri tentang implementasinya, maka itu telah dienkapsulasi (menurut pendapat programmer Python).
Sekarang, jika Anda menulis kelas Anda sedemikian rupa, Anda dapat menggunakannya tanpa harus memikirkan detail implementasi, tidak ada masalah jika Anda ingin melihat ke dalam kelas karena suatu alasan. Intinya adalah: API Anda harus bagus dan sisanya adalah detail.
Guido berkata begitu
Nah, ini tidak kontroversial: dia bilang begitu, sebenarnya . (Cari "kimono terbuka".)
Ini adalah budaya
Ya, ada beberapa alasan, tetapi tidak ada alasan kritis. Ini sebagian besar merupakan aspek budaya pemrograman dengan Python. Terus terang, bisa juga sebaliknya - tapi sebenarnya tidak. Selain itu, Anda dapat dengan mudah bertanya sebaliknya: mengapa beberapa bahasa menggunakan atribut privat secara default? Untuk alasan utama yang sama seperti untuk latihan Python: karena itu adalah budaya bahasa-bahasa ini, dan setiap pilihan memiliki kelebihan dan kekurangan.
Karena sudah ada budaya ini, sebaiknya Anda mengikutinya. Jika tidak, Anda akan terganggu oleh programmer Python yang meminta Anda untuk menghapusnya __
dari kode Anda ketika Anda mengajukan pertanyaan di Stack Overflow :)