Soal 1Di mana kamu menulis sebuah variabel class?
Variabel Class vs Variabel Instance — Di Mana Nilai Sebenarnya Berada
Panduan kaya diagram tentang variabel class vs variabel instance di Python. Lihat apa yang dibagikan, apa yang per-instance, dan apa yang sebenarnya dilakukan self.x = ....
Sebelumnya kita merampungkan penggunaan __init__ secara praktis — argumen wajib, argumen default — dan menjumpai __del__ pasangannya. Kali ini, kita akan menggali dua jenis variabel dalam class — variabel class dan variabel instance — dan melihat apa yang sebenarnya dilakukan self.x = ... di tingkat memori.
Dua Jenis Variabel
Variabel yang kamu tulis dalam class Python jatuh ke dalam dua jenis utama:
- Variabel class — ditulis langsung di bawah class Product:. Dibagikan oleh setiap instance.
- Variabel instance — ditulis sebagai self.x = ... di dalam sebuah method. Dimiliki oleh masing-masing instance secara individu.
Keduanya dibaca dengan sintaks dot apple.name yang sama, jadi kamu tidak bisa membedakan mereka dari pandangan. Itulah sebabnya kamu harus deliberatif tentang "di mana nilai sebenarnya berada."
class Product:
tax_rate = 0.1 # variabel class (dibagikan ke semua)
def __init__(self, name):
self.name = name # variabel instance (per instance)
apple = Product("apple")
banana = Product("banana")
tax_rate berada di satu tempat di Product — baik apple maupun banana melihat ke titik yang sama. Variabel instance name disimpan di memori masing-masing instance.Variabel Class — Satu Nilai Dibagikan oleh Semua
Tulis variabel class langsung di bawah class Product:, seperti tax_rate = 0.1. Bagian kuncinya adalah ia hidup di luar method mana pun. Class itu sendiri memiliki satu salinan, dan setiap instance yang dibangun dari class itu membaginya.
Kamu bisa membacanya sebagai Product.tax_rate (via class) atau apple.tax_rate (via instance). Untuk yang terakhir, Python melakukan lookup dalam urutan ini: periksa instance dulu, lalu fall back ke class.
- tax_rate = 0.1 ← variabel class (dibagikan)
- name = 'apple' ← variabel instance
- name = 'banana' ← variabel instance
class Product:
tax_rate = 0.1 # variabel class (dibagikan ke semua)
def __init__(self, name, price):
self.name = name # variabel instance (per instance)
self.price = price
apple = Product("apple", 150)
banana = Product("banana", 80)
print(Product.tax_rate) # 0.1 (via class)
print(apple.tax_rate) # 0.1 (juga bisa dibaca lewat instance)
print(banana.tax_rate) # 0.1
# Lokasi memori yang sama
print(id(apple.tax_rate) == id(Product.tax_rate)) # True
Variabel Instance — Dimiliki oleh Masing-Masing Instance
Variabel instance dibuat pada saat kamu menulis self.x = ... di dalam sebuah method, sebagai atribut eksklusif untuk instance tersebut. Paling sering kamu menginisialisasinya di __init__ dengan sesuatu seperti self.name = name, tetapi menulis self.x = ... di method lain mana pun juga membuat variabel instance baru pada saat itu.
Karena setiap instance menyimpan variabel instance di memorinya sendiri, mengubah apple.name tidak berpengaruh sama sekali pada banana.name.
apple.name dan banana.name berada di lokasi memori berbeda. Menulis ulang apple.name tidak memengaruhi banana.name sama sekali.class Product:
def __init__(self, name, price):
self.name = name
self.price = price
apple = Product("apple", 150)
banana = Product("banana", 80)
print(apple.name, apple.price) # apple 150
print(banana.name, banana.price) # banana 80
# id() menunjukkan mereka menunjuk ke tempat berbeda
print(id(apple.name) == id(banana.name)) # False
self.x = ... Membuat Variabel Instance
Misalkan Product memiliki variabel class tax_rate = 0.1, dan kamu menulis apple.tax_rate = 0.05 untuk instance tertentu — apa yang terjadi?
Jawabannya: variabel class tidak disentuh, dan variabel instance tax_rate yang baru dibuat pada apple. Sejak saat itu, apple.tax_rate mengembalikan 0.05 karena Python menemukannya pada instance dulu dan tidak pernah fall back ke class. banana sama sekali tidak terpengaruh.
class Product:
tax_rate = 0.1
def __init__(self, name, price):
self.name = name
self.price = price
apple = Product("apple", 150)
banana = Product("banana", 80)
# Berikan apple sendiri tax rate baru
apple.tax_rate = 0.05
print(apple.tax_rate) # 0.05 (variabel instance apple)
print(banana.tax_rate) # 0.1 (fall back ke variabel class)
print(Product.tax_rate) # 0.1 (variabel class tidak berubah)
apple maupun banana berbagi lookup tax_rate=0.1 pada class. Baris bawah (setelah apple.tax_rate = 0.05): variabel instance baru lahir pada apple, dan hanya apple yang membaca darinya. banana dan class tidak tersentuh.Jangan Bingungkan Ini dengan "Memperbarui Variabel Class via Instance"
apple.tax_rate = 0.05 sekilas terlihat seperti "memperbarui variabel class," tetapi itu sebenarnya hanya membuat variabel instance baru pada apple. Untuk mengubah variabel class bersama itu sendiri, kamu perlu assign melalui class: Product.tax_rate = 0.05.
Saat Kamu Ingin Memperbarui Variabel Class
Saat kamu perlu memperbarui state yang dipegang class untuk semua orang — seperti "ubah tax rate untuk semua instance sekaligus" atau "lacak jumlah kumulatif produk yang dibuat" — kamu assign melalui variabel class.
Di bawah, Product.created_count hidup di class itu sendiri dan merepresentasikan "jumlah produk yang dibuat sejauh ini." Menulis Product.created_count += 1 di dalam __init__ memperbarui titik tunggal yang sama terlepas instance mana yang sedang dibuat, jadi total berjalan tetap benar. Jika kamu menulis self.created_count += 1 sebagai gantinya, setiap instance akan memiliki variabelnya sendiri, mengalahkan tujuan asli penghitungan.
self.x += 1, setiap instance berakhir dengan salinannya sendiri, dan counter bersama tetap di 0.class Product:
created_count = 0 # variabel class: jumlah produk kumulatif
def __init__(self, name):
self.name = name
Product.created_count += 1 # perbarui melalui class
apple = Product("apple")
banana = Product("banana")
orange = Product("orange")
print(Product.created_count) # 3
print(apple.created_count) # 3 (juga bisa dibaca via instance)
Kita menyusun dua jenis variabel dalam class, mengonfirmasi bahwa self.x = ... selalu membuat variabel instance baru, bahwa variabel instance menutupi variabel class saat ada, dan bahwa state bersama diperbarui melalui class.
Cek Pemahaman
Jawab setiap pertanyaan satu per satu.
Soal 2Apa yang dicetak oleh print terakhir?class P: n = 10a = P()a.n = 99b = P()print(b.n)
Soal 3Untuk menghitung naik variabel class count di semua instance, apa yang harus kamu tulis di dalam __init__?