Semua data dalam Python berada di objek. Dan semua objek Python memiliki tipe dengan atribut dan metode terkait. Banyak tipe data asli datang dengan metode mereka sendiri untuk membuat dan menginisialisasi instance baru dan bekerja dengan berbagai operator secara default. Kelas khusus Anda tidak seberuntung itu.
Untungnya, Anda dapat memastikan bahwa kelas dan objek Anda berperilaku seperti tipe data asli ini menggunakan sesuatu yang dikenal sebagai metode dunder atau metode ajaib. Anda dapat dengan cepat mengenali operasi ini dengan garis bawah ganda atau format “dunder”: __methodname__()
. Metode ini menambahkan fungsionalitas khusus ke kelas Anda—metode konstruktor dan operator yang kelebihan beban—sehingga mereka melakukan beberapa fungsionalitas dengan kelas kustom Anda.
Setiap programmer Python harus tahu cara menggunakan metode dunder untuk memberikan fungsionalitas tipe data asli ke objek yang ditentukan pengguna Anda. Metode Dunder memungkinkan Anda untuk menyediakan kelas Anda sendiri dengan fungsionalitas yang diperkaya, merampingkan kode Anda, dan menghindari upaya yang rumit dan berantakan untuk mereplikasi fungsi yang tersedia untuk tipe data Python bawaan secara manual.
Memahami tipe data asli Python
Untuk sepenuhnya memahami metode dunder, Anda harus terlebih dahulu memahami tipe data dasar bawaan Python dan beberapa fungsi yang terkait dengannya yang dapat Anda tiru untuk kelas Anda sendiri.
Jenis objek python memiliki beberapa karakteristik. Pertama, mereka mungkin jenis objek nilai tunggal (misalnya, angka atau nilai Boolean) atau jenis objek wadah/koleksi (misalnya, daftar dan kamus).
Kedua, tipe Python bisa berubah atau tidak berubah. Jenis objek yang dapat diubah memiliki konten yang dapat dimodifikasi. Di sisi lain, jenis objek yang tidak dapat diubah tetap tetap dan tidak dapat diubah.
Setiap tipe data bawaan dalam Python memiliki kumpulan metode dundernya sendiri. Anda dapat dengan cepat melihat daftar semua metode dunder untuk tipe data menggunakan dir()
fungsi. Sebagian besar waktu, Anda tidak akan memanggil metode ini secara langsung atau mengesampingkan definisinya, karena metode tersebut terkait dengan fungsi spesifik tertentu. Sampai, tentu saja, Anda perlu menggunakannya dengan objek Anda.
Meskipun mungkin tampak terlalu mudah untuk kembali ke tipe data umum, mengetahui dasar-dasarnya sama pentingnya dengan mengetahui informasi lebih lanjut seperti cara mengidentifikasi kerentanan dalam kode Anda untuk tujuan keamanan.
numerik
Meskipun tipe numerik cukup jelas, Anda harus mengetahui tiga himpunan bagian:
Jenis Keterangan Contoh Konstruktor Bilangan bulat Bilangan bulat positif atau negatif 1, 2, 3, -1 int()
Titik-mengambang Bilangan rasional, yaitu desimal dan pecahan 1,5, 2,75, 3,5 float()
Kompleks Bilangan dengan bagian nyata dan imajiner, yang masing-masing adalah bilangan floating-point. 10 + 5j complex()
Jenis numerik memungkinkan untuk berbagai operasi matematika yang terkait dengan metode dunder. Misalnya, operator penjumlahan +
sesuai dengan metode dunder __add__()
. dunder matematika tambahan termasuk __sub__
, __mul__
, __divmod__
, __abs__
, __lt__
, __gt__
, __le__
dll. (yang juga memiliki simbol operator terkait, misalnya, -, *, / <, >).
Biasanya, Anda hanya menggunakan operator standar alih-alih fungsi-fungsi ini. Misalnya, jika Anda ingin menambahkan 10 ke angka, Anda akan menggunakan operator standar num + 10
daripada num.__add__(10)
. Namun, jika Anda ingin membuat operator standar ini bekerja dengan objek yang ditentukan pengguna, Anda perlu menerapkan metode dunder dalam tipe data.
urutan
Python memiliki beberapa tipe data asli yang berhubungan dengan urutan, baik karakter alfanumerik, bilangan biner, atau item. Jenis urutan memiliki berbagai kegunaan, termasuk penyortiran, penyimpanan, dan perulangan.
Jenis Keterangan Contoh Konstruktor Daftar Kategori terluas dari tipe data urutan mencakup beberapa subtipe:
Daftar adalah urutan yang dapat diubah (yaitu dapat dimodifikasi), biasanya dari item yang serupa atau homogen
Tuple adalah urutan yang tidak dapat diubah (yaitu tidak dapat mengubah status atau konten), terutama berguna untuk item yang berbeda atau heterogen
Rentang adalah urutan angka yang tidak dapat diubah, paling sering digunakan untuk mengelola loopDaftar: a, b, c, d, e
Tupel: 1, 2, 3
Jangkauan: 0 (nilai awal), 100 (nilai berhenti), 10 (langkah berulang) list()
tuple()
range()
Teks Jenis urutan khusus teks, jenis ini mencakup urutan karakter Unicode. Halo Dunia str()
biner Python memiliki tiga tipe data urutan biner-spesifik yang berbeda:
Byte adalah urutan byte tunggal yang tidak dapat diubah.
Array byte adalah versi byte yang bisa berubah.
tampilan memori objek memungkinkan Python untuk mengakses dan memanipulasi konten objek tipe byte tanpa terlebih dahulu menyalinnya. Jenis ini memungkinkan manipulasi objek biner dan konversi data string ke biner untuk penyimpanan mesin.Byte: 0xff
Bytearray: [0x13, 0x00, 0x00, 0x00, 0x08, 0x00]
Tampilan memori: 64 atau [10, 20, 30]
b’123’b’abc’b’\x20\xC2\xA9′byte()
bytearray()
memoryview()
Urutan dunder termasuk __contains__
, __getitem__
, __delitem__
dan banyak lagi.
Salah satu fungsi yang lebih banyak digunakan untuk data urutan adalah len()
, yang mengembalikan panjang seluruh urutan. Mencoba menggunakan built-in len()
fungsi pada kelas khusus mengembalikan kesalahan atribut. Namun, dengan menerapkan __len__
dunder di kelas Anda, Anda dapat mereplikasi fungsionalitas bawaan. Anda kemudian dapat menggunakan objek ini di mana pun Anda ingin tipe urutan asli tanpa mengubah kode.
Boolean
Tipe data asli bagian, operator bagian, Boolean adalah tipe nilai tunggal yang mengevaluasi kebenaran atau kesalahan pernyataan. Tipe data Boolean menggunakan bool()
konstruktor dan hanya memiliki dua nilai yang mungkin: benar dan salah. Boolean dunder yang sesuai adalah __bool__()
.
Anda dapat gunakan __bool__()
untuk mendefinisikan kembali kapan suatu objek akan mengembalikan true versus false. Dalam pengujian nilai kebenaran, status default suatu objek selalu benar kecuali pembuat kode menyertakan serangkaian kondisi tertentu untuk kebenaran dalam definisi kelas. Namun, jika Anda hanya ingin objek menjadi benar jika keadaan objek tertentu berada dalam kisaran tertentu, Anda akan menggunakan __bool__()
untuk mengatur kondisi untuk hasil yang benar.
Set, Pemetaan, dan Kamus
Seperti tipe lainnya, tipe data kumpulan asli (yang merupakan wadah) menyertakan varian yang dapat berubah dan tidak dapat diubah, menggunakan set()
dan beku set()
konstruktor, masing-masing. Set berbeda dari daftar di set yang koleksi tidak berurutan, di mana elemen individu harus hashable (yaitu mereka harus memiliki nilai hash konstan sepanjang umur mereka). Namun, perhatikan bahwa tipe kumpulan itu sendiri tidak dapat di-hash, meskipun berisi item yang dapat di-hash, karena dapat berubah.
Contoh set termasuk {“anjing”, “kucing”, “burung”} dan {“Alice”, “Bob”, “Carol”}.
Jenis set sangat berguna saat membandingkan kelompok item. Misalnya, Anda dapat menggunakan himpunan ketika Anda ingin menentukan keanggotaan dalam suatu grup, mengidentifikasi elemen yang sama dalam grup (yaitu perpotongan) atau elemen yang tidak sama (yaitu perbedaan dan perbedaan simetris), atau menggabungkan grup (yaitu gabungan).
Jenis kamus adalah jenis wadah yang menggunakan dict()
konstruktor. Ini menciptakan satu atau lebih pasangan kunci:nilai antara nilai (kunci) yang unik dan dapat di-hash dan item (nilai) yang berubah-ubah. Misalnya, tipe kamus mungkin memiliki pasangan kunci:nilai berikut: 1:’Halo’, 2:’dunia’.
Set, pemetaan, dan kamus, seperti urutan, dapat menggunakan berbagai dunder untuk mengakses bagian tertentu dari pemetaan. Dunder semacam itu termasuk __setitem__
, __contains__
, ___getitem__
dll.
Ada banyak tipe data yang lebih canggih di Python, termasuk kelas, iterator, dan pengecualian. Tetapi seperti yang akan kita lihat, kelas dan instance tidak selalu datang dengan metode dunder yang sama seperti tipe data lainnya.
Menggunakan metode dunder dengan Python
Metode dunder paling terkenal di Python adalah __init__()
, yang menginisialisasi status instance baru. Sebagian besar pemrogram python fokus menimpa __init__
sehingga perubahan terjadi pada instantiasi objek baru, sementara __new__
biasanya hanya membuat subkelas dari tipe data yang tidak dapat diubah. Sintaks untuk init
metode bervariasi menurut tipe data, tetapi biasanya mencakup: self
(objek yang diinisialisasi) dan satu atau lebih variabel.
Jadi, sebagai contoh, Anda baru saja mendapat email yang menjanjikan banyak Bitcoin jika Anda pertama kali memberikan sebagian kecil Bitcoin ke pengirim email, yang merupakan contoh klasik penipuan phishing. Anda ingin mulai melacak berapa banyak bitcoin yang Anda miliki di berbagai akun Anda. Anda bisa mulai dengan mendefinisikan objek dompet bitcoin seperti ini:
class btc_wallet(object): def __init__(self, wallet_name, amount): self.wallet_name = wallet_name self.amount = amount
Anda kemudian dapat menginisialisasi sebuah instance untuk setiap dompet bitcoin Anda dan menunjukkan kepada kami berapa banyak yang Anda miliki:
btcwallet1 = btc_wallet('Coinbase', 5) print("I have", btcwallet1.amount, "BTC in my", btcwallet1.wallet_name, "wallet (lucky me!)")
Ini akan menampilkan “Saya memiliki 5 BTC di dompet Coinbase saya (beruntung saya!).”
Itu btc_wallet
class adalah custom, sehingga banyak operasi standar tidak tersedia untuk digunakan dengannya. Jika kami mencoba melakukannya, kami akan mendapatkan pesan kesalahan. Tapi sekarang, mari kita lihat bagaimana kita akan menggunakan metode dunder untuk menambahkan fungsionalitas ke btc_wallet
jenis objek.
Pertama, mari buat dua dompet bitcoin lagi.
btcwallet2 = btc_wallet('Binance', 2) btcwallet3 = btc_wallet('Huobi', 25)
Jika Anda ingin menentukan berapa banyak total bitcoin yang Anda miliki di dua dompet pertama Anda, Anda akan tergoda untuk menulis:
total_btc = btcwallet1 + btcwallet2
Tetapi jika Anda menggunakan dir()
fungsi aktif btc_wallet
Anda akan melihat itu __add__
tidak hadir. Jadi kita perlu memodifikasi definisi kelas dengan metode dunder:
def __add__(self, other): return self.amount + other.amount
Sekarang kita dapat menghitung dan mencetak total kita:
total_btc = btcwallet1 + btcwallet2 print("I have a total of", total_btc, "BTC in my wallets (lucky me!)")
Dan output kami adalah “Saya memiliki total 7 BTC di dompet saya (beruntung saya!)”
Sekarang, bagaimana jika kita ingin menjumlahkan hanya dompet kita yang memiliki tiga BTC atau lebih? Kita dapat menggunakan pernyataan if then standar, memeriksa jumlah untuk setiap dompet dan hanya memasukkan yang mana btcwallet.amount > 3
. Tapi kita juga bisa kembali ke pembahasan kita tentang Boolean di atas. Anda dapat menentukan btcwallet
sehingga hanya benar jika jumlahnya lebih besar dari tiga dengan menambahkan yang berikut ke definisi kelas:
def __bool__(self): if self.amount > 3: return True return False
Sekarang Anda dapat mengatur loop untuk menghitung total dompet Anda:
total_btc = 0 for x in range (0,3): loopname = locals()['btcwallet' + (str(x+1))] if bool(loopname): total_btc = total_btc + loopname.amount
Outputnya sekarang adalah “Saya memiliki total 30 BTC di dompet saya (beruntung saya!)”. Dan Anda memang beruntung karena ini sekitar $1,2 juta.
Kita dapat menggunakan praktik kelebihan beban metode dunder ini untuk membangun fungsionalitas kelas kita, baik operasi matematika, perbandingan, atau bahkan operasi Boolean yang dibatasi.
[Note: code operation was verified using the ExtendsClass Python checker.]
Kesimpulan
Memahami bagaimana kelas asli dan fungsinya bekerja sangat penting untuk setiap programmer Python. Dan sama pentingnya untuk memahami cara memperluas metode tipe asli tersebut ke kelas dan objek yang ditentukan pengguna.
Catatan Ed: Terima kasih kepada SuperStormer dan richardec untuk umpan balik mereka pada artikel ini.
Tags: dunders, tipe asli, python