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.legsadalah atribut yang dipanggil legsdari 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 colourdoghood itu sendiri - ini adalah konsep abstrak. Ada atribut yang masuk akal di kelas. Misalnya, population_sizeadalah 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 colouratau di legsatasnya.
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 otherakan 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 colouryang "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 colourvariabel, pada anjing yang berbeda . Jadi, fido.colouradalah satu variabel, tetapi variabel spot.colourlainnya. 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), selfakan menjadi apa pun yang Anjing baru itu kelak; inside MyInteger's add, selfakan terikat ke objek dalam variabel three. Jadi,three.valueakan menjadi variabel yang sama di luar add, seperti self.valuedi dalam add.
Jika saya katakan the_mangy_one = fido, saya akan mulai mengacu pada objek yang dikenal fidodengan nama lain. Mulai sekarang, fido.colourvariabel 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. colourdengan sendirinya adalah variabel acak, bisa berisi apa saja. fido.colouratau self.colourseperti 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, fidosebenarnya bukanlah sebuah objek. Ini adalah variabel, yang saat ini berisi objek, seperti yang Anda katakan x = 5, xadalah 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 fidosejak 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, censusadalah atribut tingkat Catkelas 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 addatau __init__) adalah untuk menjelaskan cara mengonversi objek menjadi string, seperti saat Anda mencetaknya.