Dengan apa yang Anda tulis, Anda kehilangan bagian penting dari pemahaman: perbedaan antara kelas dan objek. __init__
tidak menginisialisasi kelas, itu menginisialisasi sebuah instance dari kelas atau objek. Setiap anjing memiliki warna, tetapi anjing sebagai kelas tidak. Setiap anjing memiliki empat kaki atau lebih sedikit, tetapi kelas anjing tidak. Kelas adalah konsep dari suatu objek. Saat Anda melihat Fido dan Spot, Anda mengenali kemiripan mereka, sifat anjingnya. Itu kelasnya.
Saat Anda berkata
class Dog:
def __init__(self, legs, colour):
self.legs = legs
self.colour = colour
fido = Dog(4, "brown")
spot = Dog(3, "mostly yellow")
Maksudmu, Fido adalah anjing coklat dengan 4 kaki sedangkan Spot agak cacat dan sebagian besar berwarna kuning. The __init__
fungsi disebut konstruktor, atau initializer, dan secara otomatis dipanggil ketika Anda membuat contoh baru dari sebuah kelas. Di dalam fungsi itu, objek yang baru dibuat ditugaskan ke parameter self
. Notasi self.legs
adalah atribut yang dipanggil legs
dari objek dalam variabel self
. Atribut adalah sejenis variabel, tetapi mereka menggambarkan status suatu objek, atau tindakan (fungsi) tertentu yang tersedia untuk objek tersebut.
Namun, perhatikan bahwa Anda tidak menetapkan colour
doghood itu sendiri - ini adalah konsep abstrak. Ada atribut yang masuk akal di kelas. Misalnya, population_size
adalah salah satunya - tidak masuk akal untuk menghitung Fido karena Fido selalu satu. Masuk akal untuk menghitung anjing. Katakanlah ada 200 juta anjing di dunia. Itu milik kelas Anjing. Fido tidak ada hubungannya dengan angka 200 juta, begitu juga dengan Spot. Ini disebut "atribut kelas", sebagai lawan dari "atribut contoh" yang ada colour
atau di legs
atasnya.
Sekarang, untuk sesuatu yang lebih sedikit anjing dan lebih terkait dengan pemrograman. Seperti yang saya tulis di bawah ini, kelas untuk menambahkan sesuatu tidak masuk akal - kelas apa itu? Kelas dalam Python terdiri dari kumpulan data berbeda, yang berperilaku serupa. Kelas anjing terdiri dari Fido dan Spot serta 199999999998 hewan sejenis lainnya, semuanya kencing di tiang lampu. Terdiri dari apakah kelas untuk menambahkan sesuatu? Berdasarkan data apa yang melekat pada mereka, mereka berbeda? Dan tindakan apa yang mereka bagi?
Namun, angka ... itu adalah topik yang lebih menarik. Katakanlah, Integers. Ada banyak dari mereka, lebih banyak dari pada anjing. Saya tahu bahwa Python sudah memiliki bilangan bulat, tapi mari kita bermain bodoh dan "menerapkan" mereka lagi (dengan menipu dan menggunakan bilangan bulat Python).
Jadi, Integer adalah sebuah kelas. Mereka memiliki beberapa data (nilai), dan beberapa perilaku ("tambahkan saya ke nomor lain ini"). Mari tunjukkan ini:
class MyInteger:
def __init__(self, newvalue)
# imagine self as an index card.
# under the heading of "value", we will write
# the contents of the variable newvalue.
self.value = newvalue
def add(self, other):
# when an integer wants to add itself to another integer,
# we'll take their values and add them together,
# then make a new integer with the result value.
return MyInteger(self.value + other.value)
three = MyInteger(3)
# three now contains an object of class MyInteger
# three.value is now 3
five = MyInteger(5)
# five now contains an object of class MyInteger
# five.value is now 5
eight = three.add(five)
# here, we invoked the three's behaviour of adding another integer
# now, eight.value is three.value + five.value = 3 + 5 = 8
print eight.value
# ==> 8
Ini agak rapuh (kami asumsikan other
akan menjadi MyInteger), tetapi kami akan mengabaikannya sekarang. Dalam kode nyata, kami tidak akan; kami akan mengujinya untuk memastikan, dan bahkan mungkin memaksanya ("Anda bukan bilangan bulat? Astaga, Anda memiliki 10 nanodetik untuk menjadi satu! 9 ... 8 ....")
Kita bahkan bisa mendefinisikan pecahan. Pecahan juga tahu cara menjumlahkan dirinya sendiri.
class MyFraction:
def __init__(self, newnumerator, newdenominator)
self.numerator = newnumerator
self.denominator = newdenominator
# because every fraction is described by these two things
def add(self, other):
newdenominator = self.denominator * other.denominator
newnumerator = self.numerator * other.denominator + self.denominator * other.numerator
return MyFraction(newnumerator, newdenominator)
Bahkan ada lebih banyak pecahan daripada bilangan bulat (tidak juga, tetapi komputer tidak tahu itu). Mari buat dua:
half = MyFraction(1, 2)
third = MyFraction(1, 3)
five_sixths = half.add(third)
print five_sixths.numerator
# ==> 5
print five_sixths.denominator
# ==> 6
Anda sebenarnya tidak mendeklarasikan apa pun di sini. Atribut seperti variabel jenis baru. Variabel normal hanya memiliki satu nilai. Katakanlah Anda menulis colour = "grey"
. Anda tidak dapat memiliki variabel lain bernama colour
yang "fuchsia"
- tidak di tempat yang sama dalam kode.
Array memecahkannya sampai tingkat tertentu. Jika Anda mengatakan colour = ["grey", "fuchsia"]
, Anda telah menumpuk dua warna ke dalam variabel, tetapi Anda membedakannya dengan posisinya (0, atau 1, dalam kasus ini).
Atribut adalah variabel yang terikat pada suatu objek. Seperti halnya array, kita dapat memiliki banyak colour
variabel, pada anjing yang berbeda . Jadi, fido.colour
adalah satu variabel, tetapi variabel spot.colour
lainnya. Yang pertama terikat ke objek dalam variabel fido
; yang kedua spot
,. Sekarang, saat Anda memanggil Dog(4, "brown")
, atau three.add(five)
, akan selalu ada parameter tak terlihat, yang akan ditetapkan ke ekstra yang menggantung di depan daftar parameter. Ini disebut secara konvensional self
, dan akan mendapatkan nilai benda di depan titik. Jadi, di dalam Dog __init__
(konstruktor), self
akan menjadi apa pun yang Anjing baru itu kelak; inside MyInteger
's add
, self
akan terikat ke objek dalam variabel three
. Jadi,three.value
akan menjadi variabel yang sama di luar add
, seperti self.value
di dalam add
.
Jika saya katakan the_mangy_one = fido
, saya akan mulai mengacu pada objek yang dikenal fido
dengan nama lain. Mulai sekarang, fido.colour
variabel yang sama persis dengan the_mangy_one.colour
.
Jadi, hal-hal di dalam file __init__
. Anda dapat menganggapnya sebagai catatan di dalam akta kelahiran Anjing. colour
dengan sendirinya adalah variabel acak, bisa berisi apa saja. fido.colour
atau self.colour
seperti kolom formulir pada lembar identitas Anjing; dan __init__
petugas mengisinya untuk pertama kali.
Ada yang lebih jelas?
EDIT : Memperluas komentar di bawah ini:
Maksud Anda daftar objek , bukan?
Pertama-tama, fido
sebenarnya bukanlah sebuah objek. Ini adalah variabel, yang saat ini berisi objek, seperti yang Anda katakan x = 5
, x
adalah variabel yang saat ini berisi angka lima. Jika Anda kemudian berubah pikiran, Anda dapat melakukannya fido = Cat(4, "pleasing")
(selama Anda telah membuat kelas Cat
), dan fido
sejak saat itu akan "berisi" objek kucing. Jika Anda melakukannya fido = x
, maka itu akan berisi angka lima, dan bukan objek hewan sama sekali.
Sebuah kelas dengan sendirinya tidak mengetahui kejadiannya kecuali Anda secara khusus menulis kode untuk melacaknya. Misalnya:
class Cat:
census = [] #define census array
def __init__(self, legs, colour):
self.colour = colour
self.legs = legs
Cat.census.append(self)
Di sini, census
adalah atribut tingkat Cat
kelas dari kelas.
fluffy = Cat(4, "white")
spark = Cat(4, "fiery")
Cat.census
# ==> [<__main__.Cat instance at 0x108982cb0>, <__main__.Cat instance at 0x108982e18>]
# or something like that
Perhatikan bahwa Anda tidak akan mendapatkan [fluffy, sparky]
. Itu hanya nama variabel. Jika Anda ingin kucing itu sendiri memiliki nama, Anda harus membuat atribut terpisah untuk namanya, lalu mengganti __str__
metode untuk mengembalikan nama ini. Tujuan metode ini (mis. Fungsi terikat kelas, seperti add
atau __init__
) adalah untuk menjelaskan cara mengonversi objek menjadi string, seperti saat Anda mencetaknya.