26. Method dan self — Solusi pekerjaan rumah
File solusi .py ada di
exercises/26/homework/solutions/.
Soal 1 — Object Counter
Soal. Class Counter dengan method
inc, get, dan reset.
Cara berpikir. Object menyimpan state di
self.count; setiap method membaca atau mengubahnya. Python
meneruskan object sebagai self secara otomatis ketika kamu
memanggil method pada sebuah instance.
Solusi.
class Counter:
def __init__(self):
self.count = 0
def inc(self):
self.count = self.count + 1
def get(self):
return self.count
def reset(self):
self.count = 0
counter = Counter()
counter.inc()
counter.inc()
counter.inc()
print(counter.get()) # 3
counter.reset()
print(counter.get()) # 0Kesalahan umum.
- Lupa
selfsebagai parameter pertama di setiap method. Python akan mengeluarkanTypeErroryang menyatakan method menerima 0 argumen padahal 1 diberikan. - Menulis
count = 0di level class alih-alihself.count = 0di dalam__init__. Variable di level class dibagi oleh semua instance, bukan disimpan per object.
Soal 2 — Anjing dengan gonggongan
Soal. Dua object Dog dengan nama
masing-masing, masing-masing memanggil bark()-nya
sendiri.
Cara berpikir. Setiap pemanggilan
Dog(name) menciptakan object terpisah dengan
self.name-nya sendiri. Kode method yang sama berjalan untuk
keduanya, tapi self merujuk ke object yang berbeda setiap
kali.
Solusi.
class Dog:
def __init__(self, name):
self.name = name
def bark(self):
print(f"{self.name}: Woof!")
rex = Dog("Rex")
lassie = Dog("Lassie")
rex.bark() # Rex: Woof!
lassie.bark() # Lassie: Woof!Kesalahan umum.
- Menggunakan variable global
namedi dalambarkalih-alihself.name. Kedua anjing akan mencetak nama yang sama.
Soal 3 — Object kalkulator
Soal. Object Calc dengan method
aritmetika yang memperbarui nilai internal.
Solusi.
class Calc:
def __init__(self):
self.value = 0
def add(self, n):
self.value = self.value + n
def sub(self, n):
self.value = self.value - n
def mul(self, n):
self.value = self.value * n
def show(self):
print(f"Value: {self.value}")
calc = Calc()
calc.add(10)
calc.show() # Value: 10
calc.mul(3)
calc.show() # Value: 30
calc.sub(5)
calc.show() # Value: 25Kesalahan umum.
- Mengembalikan nilai baru dari setiap method alih-alih memperbarui
self.value. Keduanya tidak masalah, tapi soal meminta pembaruan di tempat.
Tantangan — Stack
Soal. Stack LIFO dengan push,
pop, peek, size.
Solusi.
class Stack:
def __init__(self):
self.items = []
def push(self, v):
self.items.append(v)
def pop(self):
return self.items.pop()
def peek(self):
if len(self.items) == 0:
return None
return self.items[-1]
def size(self):
return len(self.items)
stack = Stack()
stack.push("a")
stack.push("b")
stack.push("c")
print(stack.size()) # 3
print(stack.peek()) # c
print(stack.pop()) # c
print(stack.pop()) # b
print(stack.size()) # 1list.append() dan list.pop() tanpa index
bekerja di ujung list — tempat yang tepat untuk operasi stack.
Kesalahan umum.
- Memanggil
self.items.pop(0)— itu menghapus dari depan, menjadikannya queue, bukan stack, dan lebih lambat karena setiap item lain bergeser. - Tidak menjaga
peek— memanggilself.items[-1]pada list kosong akan memunculkanIndexError. - Lupa mengembalikan nilai dari
popdanpeek. Default return adalahNone, yang diam-diam merusak pengujian.
Selesai?
Bab berikutnya mengembangkan pola ini lebih jauh. Dengan
class yang tepat, kamu berhenti menulis boilerplate
__init__ untuk setiap object secara terpisah dan berbagi
definisi method di banyak instance yang kamu buat dengan bersih
menggunakan pemanggilan constructor.