Belajar dengan membaca secara berurutan

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")
Di Mana Nilai Sebenarnya Berada
Productbody classtax_rate=0.1(var class)applename='apple'banananame='banana'menyimpanlookup bersamalookup bersama
Variabel class 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.

Rentang Lookup — Instance Dulu, Lalu Class
Product (ruang variabel class)
  • tax_rate = 0.1 ← variabel class (dibagikan)
apple (ruang variabel instance)
  • name = 'apple' ← variabel instance
banana (ruang variabel instance)
  • name = 'banana' ← variabel instance
Python mencari atribut dengan memeriksa instance dulu, lalu fall back ke class luar. Dari perspektif instance, variabel class bertindak seperti payung bersama di atasnya.
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

Tambahkan variabel class dan pastikan kamu bisa membacanya dari class maupun dari instance.

① Pada class Product:, tambahkan variabel class currency = "USD" di barisnya sendiri (di atas __init__).

② Tulis __init__(self, name, price) yang menetapkan self.name = name dan self.price = price.

③ Bangun apple = Product("apple", 150). Jalankan baik print(Product.currency) maupun print(apple.currency) dan pastikan keduanya menampilkan nilai yang sama.

(Jika kamu menjalankannya dengan benar, penjelasan akan muncul.)

Python Editor

Jalankan kode untuk melihat output

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.

Setiap Instance Memiliki Variabel Instance-nya Sendiri
apple(instance)name = 'apple'(memori terpisah)banana(instance)name = 'banana'(memori terpisah)menyimpanmenyimpan
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

Gunakan id() untuk merasakan bahwa variabel instance benar-benar terpisah.

① Definisikan class Product: dengan __init__(self, name, price) yang menetapkan self.name dan self.price.

② Bangun apple = Product("apple", 150) dan banana = Product("banana", 80).

③ Jalankan print(apple is banana) dan print(id(apple.name) == id(banana.name)) dan pastikan keduanya False.

Python Editor

Jalankan kode untuk melihat output

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)
Apa yang Berubah Sebelum vs Setelah Assignment
apple(tanpa var instance)banana(tanpa var instance)Producttax_rate=0.1apple.tax_rate=0.05★ barutax_rate=0.05var instance applebanana(tanpa var instance)Producttax_rate=0.1(tdk berubah)lookup bersamalookuplookup
Baris atas (sebelum): baik 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.

Pastikan secara hands-on bahwa self.x = ... membuat variabel instance baru.

① Definisikan class Product: dengan variabel class tax_rate = 0.1 dan __init__(self, name) yang menetapkan self.name = name.

② Bangun apple = Product("apple") dan banana = Product("banana").

③ Setelah apple.tax_rate = 0.05, jalankan print(apple.tax_rate), print(banana.tax_rate), dan print(Product.tax_rate). Pastikan hanya apple yang menampilkan nilai baru sementara yang lain tetap pada 0.1.

Python Editor

Jalankan kode untuk melihat output

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.

Product.x += 1 vs self.x += 1
Product.x+= 1x class tumbuhke 3total berjalanbekerjaself.x+= 1tiap instancelahirkan x barux class tetapdi 0perbaruihasilassignhasil
Assign melalui class membuat semua orang menambah counter tunggal yang sama. Dengan 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)

Bangun counter yang menambah variabel class sebesar 1 setiap kali instance dibuat.

① Pada class Product:, tambahkan variabel class created_count = 0.

② Pada __init__(self, name), setelah self.name = name, tulis Product.created_count += 1 di satu baris.

③ Buat Product("apple"), Product("banana"), dan Product("orange") secara berurutan, lalu jalankan print(Product.created_count) dan pastikan menampilkan 3.

Python Editor

Jalankan kode untuk melihat output

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.

QUIZ

Cek Pemahaman

Jawab setiap pertanyaan satu per satu.

Soal 1Di mana kamu menulis sebuah variabel class?

Soal 2Apa yang dicetak oleh print terakhir?
class P:
n = 10
a = P()
a.n = 99
b = P()
print(b.n)

Soal 3Untuk menghitung naik variabel class count di semua instance, apa yang harus kamu tulis di dalam __init__?