Saya datang dari dunia Jawa dan membaca Pola, Resep, dan Idiom Bruce Eckels ' Python 3 .
Saat membaca tentang kelas, selanjutnya dikatakan bahwa dengan Python tidak perlu mendeklarasikan variabel instan. Anda hanya menggunakannya di konstruktor, dan boom, mereka ada di sana.
Jadi misalnya:
class Simple:
def __init__(self, s):
print("inside the simple constructor")
self.s = s
def show(self):
print(self.s)
def showMsg(self, msg):
print(msg + ':', self.show())
Jika itu benar, maka objek kelas apa Simple
saja dapat mengubah nilai variabel di s
luar kelas.
Sebagai contoh:
if __name__ == "__main__":
x = Simple("constructor argument")
x.s = "test15" # this changes the value
x.show()
x.showMsg("A message")
Di Jawa, kami telah diajarkan tentang variabel publik / pribadi / yang dilindungi. Kata kunci tersebut masuk akal karena kadang-kadang Anda ingin variabel dalam suatu kelas yang tidak dapat diakses oleh siapa pun di luar kelas.
Mengapa itu tidak diperlukan dalam Python?
Jawaban:
Itu budaya. Dengan Python, Anda tidak menulis ke instance kelas atau variabel kelas lainnya. Di Jawa, tidak ada yang mencegah Anda melakukan hal yang sama jika Anda benar - benar ingin - lagipula, Anda selalu dapat mengedit sumber kelas itu sendiri untuk mencapai efek yang sama. Python menjatuhkan kepura-puraan keamanan dan mendorong programmer untuk bertanggung jawab. Dalam praktiknya, ini bekerja dengan sangat baik.
Jika Anda ingin meniru variabel pribadi karena suatu alasan, Anda selalu dapat menggunakan
__
awalan dari PEP 8 . Python membuat nama-nama variabel seperti__foo
sehingga mereka tidak mudah terlihat dengan kode di luar kelas yang berisi mereka (meskipun Anda bisa mengelilinginya jika Anda cukup bertekad, sama seperti Anda bisa berkeliling perlindungan Jawa jika Anda bekerja di dalamnya ).Dengan konvensi yang sama,
_
awalan berarti menjauh meskipun Anda secara teknis tidak dicegah melakukannya . Anda tidak bermain-main dengan variabel kelas lain yang terlihat seperti__foo
atau_bar
.sumber
Variabel pribadi dalam python lebih atau kurang adalah peretasan: penafsir sengaja mengganti nama variabel.
Sekarang, jika Anda mencoba mengakses di
__var
luar definisi kelas, itu akan gagal:Tetapi Anda dapat dengan mudah lolos dengan ini:
Anda mungkin tahu bahwa metode dalam OOP dipanggil seperti ini:,
x.printVar() => A.printVar(x)
jikaA.printVar()
dapat mengakses beberapa bidang dalamx
, bidang ini juga dapat diakses di luarA.printVar()
... setelah semua, fungsi dibuat untuk dapat digunakan kembali, tidak ada kekuatan khusus yang diberikan untuk pernyataan di dalam.Permainan berbeda ketika ada kompiler yang terlibat ( privasi adalah konsep level kompiler ). Ia tahu tentang definisi kelas dengan pengubah kontrol akses sehingga bisa kesalahan jika aturan tidak diikuti pada waktu kompilasi
sumber
Seperti yang disebutkan dengan benar oleh banyak komentar di atas, jangan lupa tujuan utama Access Modifiers: Untuk membantu pengguna kode memahami apa yang seharusnya diubah dan apa yang seharusnya tidak. Ketika Anda melihat bidang pribadi Anda tidak main-main dengan itu. Jadi sebagian besar gula sintaksis yang mudah dicapai dalam Python oleh _ dan __.
sumber
Ada variasi variabel pribadi dalam konvensi garis bawah.
Ada beberapa perbedaan halus, tetapi demi pola pemrograman kemurnian ideologis, itu cukup baik.
Ada contoh di luar sana dari dekorator pribadi @ yang lebih dekat menerapkan konsep, tetapi YMMV. Bisa dibilang orang juga bisa menulis definisi kelas yang menggunakan meta
sumber
__x
sebagai variabel di dalam kelasA
sebenarnya ditulis ulang oleh kompiler_A__x
, itu masih belum sepenuhnya pribadi dan masih dapat diakses._A__x
, saya tidak akan menyentuhnya. Itu bisa menular. Saya akan lari dari itu."Di java, kita telah diajarkan tentang variabel publik / pribadi / yang dilindungi"
"Kenapa itu tidak diperlukan dengan python?"
Untuk alasan yang sama, itu tidak diperlukan di Jawa.
Anda bebas menggunakan - atau tidak menggunakan
private
danprotected
.Sebagai programmer Python dan Java, saya telah menemukan itu
private
danprotected
sangat, konsep desain yang sangat penting. Tetapi sebagai hal praktis, dalam puluhan ribu baris Java dan Python, saya tidak pernah benar - benar menggunakanprivate
atauprotected
.Kenapa tidak?
Inilah pertanyaan saya "dilindungi dari siapa?"
Pemrogram lain di tim saya? Mereka punya sumbernya. Apa artinya dilindungi ketika mereka dapat mengubahnya?
Pemrogram lain di tim lain? Mereka bekerja untuk perusahaan yang sama. Mereka dapat - dengan panggilan telepon - mendapatkan sumbernya.
Klien? Ini program kerja-untuk-merekrut (umumnya). Klien (umumnya) memiliki kodenya.
Jadi, siapa - tepatnya - di mana saya melindunginya?
sumber
Seperti yang disebutkan sebelumnya, Anda dapat menunjukkan bahwa variabel atau metode bersifat pribadi dengan awalan dengan garis bawah. Jika Anda merasa ini tidak cukup, Anda selalu dapat menggunakan
property
dekorator. Ini sebuah contoh:Dengan cara ini, seseorang atau sesuatu yang direferensikan
bar
sebenarnya mereferensikan nilai pengembalianbar
fungsi daripada variabel itu sendiri, dan oleh karena itu dapat diakses tetapi tidak diubah. Namun, jika seseorang benar-benar menginginkannya, mereka bisa menggunakan_bar
dan memberikan nilai baru padanya. Tidak ada cara pasti untuk mencegah seseorang mengakses variabel dan metode yang ingin Anda sembunyikan, seperti yang telah dikatakan berulang kali. Namun, menggunakanproperty
adalah pesan yang paling jelas yang dapat Anda kirim bahwa suatu variabel tidak dapat diedit.property
juga dapat digunakan untuk jalur akses pengambil / penyetel / deleter yang lebih kompleks, seperti yang dijelaskan di sini: https://docs.python.org/3/library/functions.html#propertysumber
Python memiliki dukungan terbatas untuk pengidentifikasi pribadi, melalui fitur yang secara otomatis menambahkan nama kelas ke pengidentifikasi apa pun yang dimulai dengan dua garis bawah. Ini transparan untuk programmer, sebagian besar, tetapi efek bersihnya adalah bahwa setiap variabel bernama cara ini dapat digunakan sebagai variabel pribadi.
Lihat di sini untuk lebih lanjut tentang itu.
Secara umum, implementasi orientasi objek Python sedikit primitif dibandingkan dengan bahasa lain. Tapi sebenarnya saya menikmati ini. Ini adalah implementasi yang sangat sederhana secara konseptual dan sangat cocok dengan gaya bahasa yang dinamis.
sumber
Satu-satunya waktu saya menggunakan variabel pribadi adalah ketika saya perlu melakukan hal-hal lain ketika menulis ke atau membaca dari variabel dan karena itu saya harus memaksa penggunaan setter dan / atau pengambil.
Sekali lagi ini berlaku untuk budaya, seperti yang telah disebutkan. Saya telah mengerjakan proyek-proyek di mana membaca dan menulis variabel kelas lain adalah gratis untuk semua. Ketika satu implementasi menjadi usang butuh waktu lebih lama untuk mengidentifikasi semua jalur kode yang menggunakan fungsi itu. Ketika penggunaan setter dan getter terpaksa, pernyataan debug dapat dengan mudah ditulis untuk mengidentifikasi bahwa metode yang sudah usang telah dipanggil dan jalur kode yang menyebutnya.
Ketika Anda berada di proyek di mana siapa pun dapat menulis ekstensi, memberi tahu pengguna tentang metode usang yang akan menghilang dalam beberapa rilis maka sangat penting untuk menjaga kerusakan modul seminimal mungkin pada saat upgrade.
Jadi jawaban saya adalah; jika Anda dan kolega Anda mempertahankan satu set kode sederhana maka melindungi variabel kelas tidak selalu diperlukan. Jika Anda menulis sistem yang dapat diperluas maka menjadi penting ketika perubahan pada inti dibuat yang perlu ditangkap oleh semua ekstensi menggunakan kode.
sumber
Maaf guys untuk "menghidupkan kembali" utas, tapi, saya harap ini akan membantu seseorang:
Di Python3 jika Anda hanya ingin "merangkum" atribut kelas, seperti di Jawa, Anda bisa melakukan hal yang sama seperti ini:
Untuk instantiate ini lakukan:
Perhatikan bahwa:
print(ss.__s)
akan menimbulkan kesalahan.Dalam praktiknya, Python3 akan mengaburkan nama atribut global. Mengubah ini seperti atribut "pribadi", seperti di Jawa. Nama atribut masih bersifat global, tetapi dengan cara yang tidak dapat diakses, seperti atribut pribadi dalam bahasa lain.
Tapi jangan takut. Itu tidak masalah. Itu melakukan pekerjaan juga. ;)
sumber
konsep pribadi dan dilindungi sangat penting. Tapi python - hanya alat untuk membuat prototipe dan pengembangan cepat dengan sumber daya terbatas yang tersedia untuk pengembangan, itu sebabnya beberapa tingkat perlindungan tidak begitu ketat diikuti oleh python. Anda dapat menggunakan "__" di anggota kelas, itu berfungsi dengan baik, tetapi terlihat tidak cukup baik - setiap akses ke bidang tersebut berisi karakter ini.
Anda juga dapat memperhatikan bahwa konsep python OOP tidak sempurna, smaltalk atau ruby lebih dekat dengan konsep OOP murni. Bahkan C # atau Java lebih dekat.
Python adalah alat yang sangat bagus. Tetapi ini adalah bahasa OOP yang disederhanakan. Secara sintaksis dan konseptual disederhanakan. Tujuan utama dari keberadaan python adalah untuk membawa kepada pengembang kemungkinan untuk menulis kode yang mudah dibaca dengan tingkat abstraksi yang tinggi dengan cara yang sangat cepat.
sumber
Python tidak memiliki variabel pribadi seperti C ++ atau Java. Anda dapat mengakses variabel anggota mana saja kapan saja jika diinginkan. Namun, Anda tidak memerlukan variabel pribadi dalam Python, karena dalam Python tidak buruk untuk mengekspos variabel anggota kelas Anda. Jika Anda perlu merangkum variabel anggota, Anda dapat melakukan ini dengan menggunakan "@ properti" nanti tanpa melanggar kode klien yang ada.
Dalam python, garis bawah tunggal "_" digunakan untuk menunjukkan, bahwa suatu metode atau variabel tidak dianggap sebagai bagian dari api publik suatu kelas dan bahwa bagian api ini dapat berubah di antara versi yang berbeda. Anda dapat menggunakan metode / variabel ini, tetapi kode Anda dapat rusak, jika Anda menggunakan versi yang lebih baru dari kelas ini.
Garis ganda berganda "__" tidak berarti "variabel pribadi". Anda menggunakannya untuk mendefinisikan variabel yang merupakan "kelas lokal" dan yang tidak dapat dengan mudah dikuasai oleh subkelas. Ini mangles nama variabel.
Sebagai contoh:
self .__ nama foobar secara otomatis di-mangled ke self._A__foobar di kelas A. Di kelas B itu di-mangled ke self._B__foobar. Jadi setiap subclass dapat mendefinisikan variabel sendiri __foobar tanpa mengesampingkan variabel induknya. Tapi tidak ada yang mencegah Anda mengakses variabel yang dimulai dengan garis bawah ganda. Namun, pengubahan nama mencegah Anda memanggil variabel / metode ini secara tidak sengaja.
Saya sangat merekomendasikan untuk menonton Raymond Hettingers berbicara "Toolkit pengembangan kelas Python" dari Pycon 2013 (harus tersedia di Youtube), yang memberikan contoh yang baik mengapa dan bagaimana Anda harus menggunakan @property dan "__" - variabel instan.
sumber
@property
hal itu bagian dari Python standar, atau khusus untuk IDE?property
fungsi builtin, yang tersedia sejak python 2.2Sebenarnya Anda dapat mensimulasikan
C#
pengambil dan penyetel menggunakan trik sederhana ini:Kemudian gunakan yang serupa seperti di
C#
:Itu hanya mendeklarasikan variabel lokal statis dalam suatu fungsi yang akan memainkan peran get / set, karena itulah satu-satunya cara untuk membagikan variabel melalui metode get and set, tanpa membuatnya global untuk kelas atau file.
sumber