Enkapsulasi dalam Python 3

gambar


Definisi


Arti istilah "enkapsulasi" tidak jelas dan berbeda dari sumber ke sumber. Secara umum diterima bahwa enkapsulasi adalah salah satu prinsip dasar OOP, meskipun beberapa artikel ilmiah sepenuhnya menghilangkan enkapsulasi dari daftar. Sebagai contoh, John Mitchell dalam buku "Konsep dalam Bahasa Pemrograman", ketika mendaftar konsep utama dalam OOP, hanya menyebutkan abstraksi - sebuah istilah yang dianggap dekat dengan enkapsulasi dengan makna, namun demikian lebih luas dan tingkat lebih tinggi. Robert Martin, di sisi lain, dalam bukunya Pure Architecture, secara eksplisit menyatakan bahwa enkapsulasi, pewarisan, dan polimorfisme dianggap sebagai dasar dari OOP.


Variasi definisi yang diberikan untuk istilah "enkapsulasi" sulit untuk dibawa ke penyebut umum. Secara umum, dua pendekatan terhadap makna istilah ini dapat dibedakan. Enkapsulasi dapat dianggap sebagai:


  • komunikasi data dengan metode yang mengontrol data ini;
  • Seperangkat alat untuk mengontrol akses ke data atau metode yang mengelola data ini.

Enkapsulasi sebagai koneksi


Interpretasi semacam ini dari istilah "enkapsulasi" sangat mudah untuk dijelaskan. Dalam hal ini, setiap kelas di mana setidaknya ada satu variabel dan satu metode yang mengontrolnya dengan jelas menunjukkan prinsip ini.


#!/usr/bin/python3 class Phone: number = "111-11-11" def print_number(self): print( "Phone number is: ", self.number ) my_phone = Phone() my_phone.print_number() input( "Press Enter to exit" ) 

Kelas Telepon menggabungkan data dalam nomor variabel dengan metode print_number ()


Anda bisa membuat kelas yang hanya terdiri dari metode (dan tidak mengandung variabel), yang mungkin nyaman di beberapa bahasa pemrograman. Dimungkinkan juga untuk membuat kelas yang hanya berisi data, tanpa metode, yang, dalam banyak kasus, harus dihindari. Kedua praktik tersebut harus diterapkan bila perlu, dan hubungannya dengan enkapsulasi "pemersatu" masih bisa diperdebatkan.


Enkapsulasi sebagai Kontrol Akses


Menjelaskan konsep membatasi akses ke data atau metode membutuhkan lebih banyak detail. Pertama-tama, dalam konteks ini, istilah "akses" harus dipahami sebagai kemampuan untuk melihat dan / atau memodifikasi konten internal suatu kelas. Ada beberapa tingkat akses yang disediakan oleh sebagian besar bahasa OOP. Meringkas, kita dapat mengatakan bahwa data objek dapat:


  • publik ( public ) - data tersedia untuk semua orang;
  • private ( private ) - data hanya tersedia untuk objek / kelas yang dimilikinya.

Sebagian besar bahasa memiliki derajat akses tambahan yang berada di antara batas-batas ini. Misalnya, dalam C ++ dan Python3 ada tiga tingkat akses: publik, dilindungi dan pribadi; C # menambahkan kata kunci "internal" ke daftar.


Perlu dicatat bahwa di sebagian besar bahasa pemrograman, tingkat akses ke data apa pun diatur secara default. Misalnya, dalam C ++, secara default, tingkat akses data di kelas diatur ke pribadi - hanya anggota dan teman-teman kelas yang dapat mengakses datanya. Tingkat standar akses ke struktur ( struct ) di C ++ berbeda - itu bersifat publik, dan data dalam struktur seperti itu dapat diakses oleh siapa saja. Level akses untuk variabel dan metode kelas di Python 3 sepenuhnya bergantung pada sintaksis.


Contohnya


Enkapsulasi


Python 3 menyediakan 3 level akses data:


  • public ( public , tidak ada sintaks khusus, publicBanana );
  • protected ( protected , satu garis bawah pada awal nama, _protectedBanana );
  • pribadi ( private , dua garis bawah pada awal nama, __privateBanana ).

Untuk singkatnya dan kesederhanaan, hanya dua tingkat dasar (swasta dan publik) yang disorot dalam contoh.


 #!/usr/bin/python3 class Phone: username = "Kate" # public variable __how_many_times_turned_on = 0 # private variable def call(self): # public method print( "Ring-ring!" ) def __turn_on(self): # private method self.__how_many_times_turned_on += 1 print( "Times was turned on: ", self.__how_many_times_turned_on ) my_phone = Phone() my_phone.call() print( "The username is ", my_phone.username ) # my_phone.turn_on() # my_phone.__turn_on() # print( โ€œTurned on: โ€œ, my_phone.__how_many_times_turned_on) # print( โ€œTurned on: โ€œ, my_phone.how_many_times_turned_on) # will produce an error input( "Press Enter to exit" ) 

Akses ke variabel dan metode publik dapat diperoleh dari program utama. Mencoba mengambil data pribadi atau menjalankan metode pribadi akan menghasilkan kesalahan.


Pelanggaran enkapsulasi


Bahasa itu sendiri menyediakan programmer dengan alat sintaks yang dapat menghindari enkapsulasi. Membaca dan memodifikasi variabel pribadi dan memanggil fungsi pribadi masih dimungkinkan.


 #!/usr/bin/python3 class Phone: username = "Kate" # public variable __serial_number = "11.22.33" # private variable __how_many_times_turned_on = 0 # private variable def call(self): # public method print( "Ring-ring!" ) def __turn_on(self): # private method self.__how_many_times_turned_on += 1 print( "Times was turned on: ", self.__how_many_times_turned_on ) my_phone = Phone() my_phone._Phone__turn_on() my_phone._Phone__serial_number = "44.55.66" print( "New serial number is ", my_phone._Phone__serial_number ) input( "Press Enter to exit" ) 

Beberapa kata tentang Sihir


Ada metode, yang disebut "metode ajaib" atau "metode khusus", yang memungkinkan kelas untuk menentukan perilaku mereka sehubungan dengan operator bahasa standar. Ekspresi berikut dapat berfungsi sebagai contoh dari operator bahasa tersebut:


  • x > y
  • x[ i ]

Python 3 mendukung banyak metode ini, daftar lengkap dapat ditemukan di halaman dokumentasi bahasa resmi. __init__ (initializer) adalah yang paling umum digunakan dan dimulai ketika objek kelas baru dibuat. Yang lainnya, __lt__ (perbandingan lanjutan), mendefinisikan aturan untuk membandingkan dua objek dari kelas pengguna. Metode seperti itu tidak termasuk dalam kategori "pribadi" atau "publik", karena mereka melayani tujuan lain dan sangat berakar dalam struktur internal bahasa.


 #!/usr/bin/python3 class Phone: def __init__(self, number): # magic method / inititalizer print( "The Phone object was created" ) self.number = number def __lt__(self, other): # magic method / rich comparison return self.number < other.number my_phone = Phone(20) other_phone = Phone(30) if my_phone < other_phone: print( "Two instances of custom class were compared" ) print( "'__lt__' was called implicitly" ) if my_phone.__lt__(other_phone): print( "Now, '__lt__' was used explicitly" ) input( "Press Enter to exit" ) 

Metode ajaib dapat dipanggil oleh pengguna mana pun dengan cara yang sama dengan metode publik apa pun di Python, namun metode tersebut dimaksudkan untuk digunakan secara implisit dalam kasus khusus mereka. Kasus khusus untuk metode __init__ adalah inisialisasi objek kelas baru. __lt__ digunakan untuk membandingkan dua objek.


Kesimpulan


Python3 tidak menyediakan akses terbatas ke variabel atau metode kelas apa pun. Data yang harus disembunyikan sebenarnya bisa dibaca dan dimodifikasi. Dalam Python3, enkapsulasi lebih merupakan konvensi, dan programmer harus menjaga melestarikannya sendiri.


Sumber


  1. John C. Mitchell, Konsep dalam bahasa pemrograman
  2. Robert C. Martin, Arsitektur Bersih, Panduan Pengrajin untuk Struktur dan Desain Perangkat Lunak

Source: https://habr.com/ru/post/id444338/


All Articles