2.21. Metode dan atribut¶
Metode adalah fungsi yang didefinisikan di dalam kelas. Parameter pertama adalah instans tempat metode dipanggil; konvensionalnya diberi nama self.
2.21.1. Metode instans¶
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def magnitude(self):
return (self.x ** 2 + self.y ** 2) ** 0.5
p = Point(3, 4)
print(p.magnitude())
Output:
5.0
Panggilan p.magnitude() meneruskan p sebagai self secara otomatis. Badan metode membaca dan memperbarui atribut melalui self dengan cara yang sama fungsi membaca dan memperbarui nama melalui parameter.
2.21.2. Atribut instans vs kelas¶
Atribut yang ditugaskan ke self -- biasanya di dalam __init__ -- milik instans tersebut saja:
a = Point(1, 2)
b = Point(10, 20)
a.x = 99
print(a.x, b.x) # 99 10
a.x dan b.x adalah penyimpanan yang berbeda; mengubah satu tidak mempengaruhi yang lain.
Nama yang ditugaskan di badan kelas, di luar metode apa pun, dibagikan oleh setiap instans kelas:
class Counter:
kind = "tally" # class attribute -- shared
def __init__(self):
self.value = 0 # instance attribute -- per instance
a = Counter()
b = Counter()
print(a.kind, b.kind) # tally tally
Atribut kelas berada di kelas itu sendiri dan dibagikan. Atribut instans berada di setiap instans.¶
Atribut kelas dicapai dengan cara yang sama seperti atribut instans (a.kind); Python pertama-tama mencari di instans, kemudian di kelas. Menetapkan ke a.kind akan membuat atribut instans baru yang menutupi atribut kelas, membiarkan b.kind tidak tersentuh.
Gunakan atribut kelas untuk konstanta dan default yang setiap instans harus lihat dengan cara yang sama. Gunakan atribut instans untuk status yang setiap objek harus memiliki salinannya sendiri.
2.21.3. __str__ dan __repr__¶
Dua metode khusus mengontrol cara instans dicetak. __str__ mengembalikan string "ramah" yang digunakan oleh print(); __repr__ mengembalikan string "pengembang" yang digunakan di REPL dan di dalam tampilan wadah:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return "(" + str(self.x) + ", " + str(self.y) + ")"
def __repr__(self):
return "Point(" + str(self.x) + ", " + str(self.y) + ")"
p = Point(3, 4)
print(p) # uses __str__
print([p, p]) # uses __repr__ inside the list
Output:
(3, 4)
[Point(3, 4), Point(3, 4)]
Jika hanya __repr__ yang didefinisikan, print() akan kembali ke sana -- jadi __repr__ yang ditulis dengan baik biasanya sudah cukup. Definisikan __str__ juga hanya ketika bentuk ramah harus terlihat berbeda dari bentuk pengembang. Usahakan membuat __repr__ yang terlihat seperti panggilan yang akan membuat ulang objek; proses debug menjadi jauh lebih mudah ketika nilai yang dicetak tidak ambigu.