จากสิ่งที่คุณเขียนคุณกำลังขาดความเข้าใจที่สำคัญนั่นคือความแตกต่างระหว่างคลาสและวัตถุ __init__
ไม่ได้เตรียมใช้งานคลาสโดยเริ่มต้นอินสแตนซ์ของคลาสหรืออ็อบเจ็กต์ สุนัขแต่ละตัวมีสี แต่สุนัขในชั้นเรียนไม่มี สุนัขแต่ละตัวมีเท้าไม่เกินสี่ฟุต แต่ระดับของสุนัขไม่มี คลาสเป็นแนวคิดของวัตถุ เมื่อคุณเห็น Fido และ Spot คุณจะรับรู้ถึงความคล้ายคลึงกันความกระตือรือร้นของพวกเขา นั่นคือชั้นเรียน
เมื่อคุณพูดว่า
class Dog:
def __init__(self, legs, colour):
self.legs = legs
self.colour = colour
fido = Dog(4, "brown")
spot = Dog(3, "mostly yellow")
คุณกำลังพูดว่า Fido เป็นสุนัขสีน้ำตาลที่มี 4 ขาในขณะที่ Spot เป็นคนพิการเล็กน้อยและส่วนใหญ่เป็นสีเหลือง __init__
ฟังก์ชั่นที่เรียกว่าคอนสตรัคหรือการเริ่มต้นและมีการเรียกโดยอัตโนมัติเมื่อคุณสร้างตัวอย่างใหม่ของชั้นเรียน self
ภายในฟังก์ชันที่วัตถุที่สร้างขึ้นใหม่ได้รับมอบหมายให้พารามิเตอร์ สัญกรณ์self.legs
เป็นคุณลักษณะที่เรียกว่าของวัตถุในตัวแปรlegs
self
แอตทริบิวต์เป็นเหมือนตัวแปร แต่อธิบายสถานะของวัตถุหรือการกระทำ (ฟังก์ชัน) ที่มีให้กับวัตถุ
อย่างไรก็ตามโปรดสังเกตว่าคุณไม่ได้ตั้งเป้าหมายไว้ที่colour
ความมุ่งมั่น แต่เป็นแนวคิดนามธรรม มีคุณลักษณะที่เหมาะสมกับชั้นเรียน ตัวอย่างpopulation_size
เช่นมันไม่สมเหตุสมผลที่จะนับ Fido เพราะ Fido เป็นหนึ่งเสมอ การนับสุนัขเป็นเรื่องที่สมเหตุสมผล สมมติว่ามีสุนัข 200 ล้านตัวในโลก เป็นสมบัติของคลาส Dog Fido ไม่มีส่วนเกี่ยวข้องกับจำนวน 200 ล้านหรือ Spot มันเรียกว่า "ชั้นแอตทริบิวต์" เมื่อเทียบกับ "คุณลักษณะเช่น" ที่มีcolour
หรือlegs
ข้างต้น
ตอนนี้เป็นสิ่งที่สุนัขน้อยและเกี่ยวข้องกับการเขียนโปรแกรมมากขึ้น ตามที่ฉันเขียนไว้ด้านล่างคลาสเพื่อเพิ่มสิ่งต่างๆไม่สมเหตุสมผล - คลาสของอะไร? คลาสใน Python ประกอบด้วยคอลเล็กชันของข้อมูลที่แตกต่างกันซึ่งทำงานในลักษณะเดียวกัน ประเภทของสุนัขประกอบด้วย Fido และ Spot และ 199999999998 สัตว์อื่น ๆ ที่คล้ายกับพวกมันทุกตัวกำลังฉี่บนเสาไฟ คลาสสำหรับเพิ่มสิ่งต่างๆประกอบด้วยอะไรบ้าง? ข้อมูลที่มีอยู่ในตัวพวกเขาแตกต่างกันอย่างไร? และพวกเขาแบ่งปันการกระทำอะไรบ้าง?
อย่างไรก็ตามตัวเลข ... เป็นวิชาที่น่าสนใจกว่า พูดว่าจำนวนเต็ม มีจำนวนมากมากกว่าสุนัข ฉันรู้ว่า Python มีจำนวนเต็มอยู่แล้ว แต่เรามาเล่นโง่ ๆ และ "ใช้" อีกครั้ง (โดยการโกงและใช้จำนวนเต็มของ Python)
ดังนั้นจำนวนเต็มจึงเป็นคลาส พวกเขามีข้อมูลบางอย่าง (ค่า) และพฤติกรรมบางอย่าง ("เพิ่มฉันในหมายเลขอื่นนี้") มาแสดงสิ่งนี้:
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
นี่ค่อนข้างบอบบาง (เราสมมติว่าother
เป็น MyInteger) แต่ตอนนี้เราจะไม่สนใจ ในรหัสจริงเราจะไม่; เราจะทดสอบเพื่อให้แน่ใจและอาจจะบังคับด้วยซ้ำ ("คุณไม่ใช่จำนวนเต็มเหรอโดย golly คุณมี 10 นาโนวินาทีที่จะกลายเป็นหนึ่ง 9 ... 8 .... ")
เราสามารถกำหนดเศษส่วนได้ เศษส่วนยังรู้วิธีเพิ่มตัวเอง
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)
มีเศษส่วนมากกว่าจำนวนเต็ม (ไม่จริง แต่คอมพิวเตอร์ไม่รู้) ลองสร้างสอง:
half = MyFraction(1, 2)
third = MyFraction(1, 3)
five_sixths = half.add(third)
print five_sixths.numerator
# ==> 5
print five_sixths.denominator
# ==> 6
คุณไม่ได้ประกาศอะไรที่นี่ แอตทริบิวต์เปรียบเสมือนตัวแปรชนิดใหม่ ตัวแปรปกติมีเพียงค่าเดียว colour = "grey"
ให้เราบอกคุณเขียน คุณไม่สามารถตั้งชื่อตัวแปรอื่นcolour
ที่เป็น"fuchsia"
- ไม่ได้อยู่ในตำแหน่งเดียวกันในโค้ด
อาร์เรย์แก้ปัญหานั้นในระดับหนึ่ง ถ้าคุณบอกว่าcolour = ["grey", "fuchsia"]
คุณได้ซ้อนสีสองสีไว้ในตัวแปร แต่คุณแยกความแตกต่างตามตำแหน่ง (0 หรือ 1 ในกรณีนี้)
แอตทริบิวต์คือตัวแปรที่ผูกไว้กับวัตถุ เช่นเดียวกับอาร์เรย์เราสามารถมีความอุดมสมบูรณ์colour
ตัวแปรในสุนัขที่แตกต่างกัน ดังนั้นfido.colour
เป็นหนึ่งในตัวแปร แต่spot.colour
เป็นอีกหนึ่ง คนแรกที่ถูกผูกไว้กับวัตถุที่อยู่ภายในตัวแปรfido
; ที่สอง, spot
. ตอนนี้เมื่อคุณเรียกDog(4, "brown")
หรือthree.add(five)
จะมีพารามิเตอร์ที่มองไม่เห็นอยู่เสมอซึ่งจะถูกกำหนดให้กับตัวห้อยพิเศษที่ด้านหน้าของรายการพารามิเตอร์ เรียกตามอัตภาพself
และจะได้รับค่าของวัตถุที่อยู่หน้าจุด ดังนั้นภายใน Dog's __init__
(ผู้สร้าง) self
จะเป็นอะไรก็ตามที่สุนัขตัวใหม่จะกลายเป็น; ภายในMyInteger
's add
, จะถูกผูกไว้กับวัตถุในตัวแปรself
three
ดังนั้นthree.value
จะเป็นตัวแปรเดียวกับภายนอกadd
เช่นเดียวกับself.value
ภายในadd
.
ถ้าฉันพูดthe_mangy_one = fido
ฉันจะเริ่มอ้างถึงวัตถุที่รู้จักกันในfido
ชื่ออื่น จากนี้ไปfido.colour
เป็นตัวแปรเดียวกับthe_mangy_one.colour
.
ดังนั้นสิ่งที่อยู่ภายใน__init__
. คุณอาจคิดว่าพวกเขาสังเกตเห็นสิ่งต่างๆในสูติบัตรของสุนัข colour
โดยตัวมันเองเป็นตัวแปรสุ่มอาจมีอะไรก็ได้ fido.colour
หรือself.colour
เป็นเหมือนช่องแบบฟอร์มบนแผ่นข้อมูลประจำตัวของสุนัข และ__init__
เป็นเสมียนกรอกข้อมูลเป็นครั้งแรก
ชัดเจนกว่านี้ไหม
แก้ไข : ขยายความคิดเห็นด้านล่าง:
คุณหมายถึงรายการวัตถุใช่ไหม
ประการแรกfido
ไม่ใช่วัตถุ มันเป็นตัวแปรซึ่งขณะนี้มีวัตถุเช่นเดียวกับเมื่อคุณพูดx = 5
, x
เป็นตัวแปรในปัจจุบันมีจำนวนห้า หากคุณเปลี่ยนใจในภายหลังคุณสามารถทำได้fido = Cat(4, "pleasing")
(ตราบเท่าที่คุณสร้างคลาสCat
) และfido
จากนั้นจะ "มี" วัตถุที่เป็นแมว ถ้าคุณทำfido = x
มันจะมีตัวเลขห้าไม่ใช่สัตว์เลย
คลาสโดยตัวมันเองจะไม่รู้จักอินสแตนซ์ของมันเว้นแต่คุณจะเขียนโค้ดเพื่อติดตามมันโดยเฉพาะ ตัวอย่างเช่น:
class Cat:
census = [] #define census array
def __init__(self, legs, colour):
self.colour = colour
self.legs = legs
Cat.census.append(self)
นี่census
คือแอตทริบิวต์Cat
ระดับชั้นของคลาส
fluffy = Cat(4, "white")
spark = Cat(4, "fiery")
Cat.census
# ==> [<__main__.Cat instance at 0x108982cb0>, <__main__.Cat instance at 0x108982e18>]
# or something like that
[fluffy, sparky]
โปรดทราบว่าคุณจะไม่ได้รับ นี่เป็นเพียงชื่อตัวแปร หากคุณต้องการให้แมวมีชื่อคุณต้องสร้างแอตทริบิวต์แยกต่างหากสำหรับชื่อจากนั้นจึงแทนที่__str__
เมธอดเพื่อส่งคืนชื่อนี้ วัตถุประสงค์ของเมธอดนี้ (เช่นฟังก์ชันที่มีขอบเขตคลาสเช่นเดียวกับadd
หรือ__init__
) คือการอธิบายวิธีการแปลงวัตถุเป็นสตริงเช่นเมื่อคุณพิมพ์ออกมา