ใน Python คุณสร้างคลาสย่อยจากซูเปอร์คลาสได้อย่างไร?
ใน Python คุณสร้างคลาสย่อยจากซูเปอร์คลาสได้อย่างไร?
คำตอบ:
# Initialize using Parent
#
class MySubClass(MySuperClass):
def __init__(self):
MySuperClass.__init__(self)
หรือที่ดีกว่านั้นคือการใช้ฟังก์ชันในตัวของ Python super()
(ดูเอกสารประกอบPython 2 / Python 3 ) อาจเป็นวิธีที่ดีกว่าเล็กน้อยในการเรียกพาเรนต์สำหรับการเริ่มต้น:
# Better initialize using Parent (less redundant).
#
class MySubClassBetter(MySuperClass):
def __init__(self):
super(MySubClassBetter, self).__init__()
หรือสิ่งที่แน่นอนเช่นเดียวกับด้านบนยกเว้นการใช้รูปแบบอาร์กิวเมนต์เป็นศูนย์super()
ซึ่งใช้ได้เฉพาะในนิยามคลาส
class MySubClassBetter(MySuperClass):
def __init__(self):
super().__init__()
super
โดยเฉพาะอย่างยิ่งสำหรับโปรแกรมเมอร์ Python ใหม่ (เช่น Lutz) ฉันหลีกเลี่ยงมัน
super
คือหากคุณไม่เข้าใจความแตกต่างระหว่างวิธีการsuper
ทำงานใน Python และวิธีการsuper
/ parent
ทำงานในภาษาอื่น เป็นที่ยอมรับว่าสิ่งนี้ไม่ชัดเจนสำหรับผู้ที่มาจากภาษาอื่น แต่ฉันจะไม่สรุปว่าสิ่งนี้ถือว่าเป็นสิ่งที่ "ควรระวัง" มันไม่ทำงาน มันทำงานแตกต่างกัน เพียงอ่านเกี่ยวกับสิ่งที่มันทำใน Python ก่อนที่คุณจะบ่นเกี่ยวกับผลลัพธ์ที่คุณไม่คาดคิด
ตัวอย่างเล็ก ๆ น้อย ๆ ที่กล้าหาญ:
class SuperHero(object): #superclass, inherits from default object
def getName(self):
raise NotImplementedError #you want to override this on the child classes
class SuperMan(SuperHero): #subclass, inherits from SuperHero
def getName(self):
return "Clark Kent"
class SuperManII(SuperHero): #another subclass
def getName(self):
return "Clark Kent, Jr."
if __name__ == "__main__":
sm = SuperMan()
print sm.getName()
sm2 = SuperManII()
print sm2.getName()
class MySubClass(MySuperClass):
def __init__(self):
MySuperClass.__init__(self)
# <the rest of your custom initialization code goes here>
ส่วนที่เกี่ยวกับการรับมรดกในเอกสารหลามอธิบายในรายละเอียดมากขึ้น
__init__
วิธีการนั้นหากต้องการเพิ่มรหัสเพิ่มเติมมิฉะนั้นจะใช้วิธีการเริ่มต้นเดิมต่อไป (แม้ว่าจะคุ้มค่าที่จะกล่าวถึงและเป็นรหัสที่ถูกต้องอย่างสมบูรณ์)
class Class1(object):
pass
class Class2(Class1):
pass
Class2 เป็นคลาสย่อยของ Class1
ในคำตอบข้างต้นคำตอบsuper
จะเริ่มต้นโดยไม่มีอาร์กิวเมนต์ (คีย์เวิร์ด) อย่างไรก็ตามบ่อยครั้งที่คุณต้องการทำเช่นนั้นรวมทั้งส่งต่อข้อโต้แย้งที่ "กำหนดเอง" ของคุณเอง นี่คือตัวอย่างที่แสดงกรณีการใช้งานนี้:
class SortedList(list):
def __init__(self, *args, reverse=False, **kwargs):
super().__init__(*args, **kwargs) # Initialize the super class
self.reverse = reverse
self.sort(reverse=self.reverse) # Do additional things with the custom keyword arguments
นี่คือคลาสย่อยlist
ที่เมื่อเริ่มต้นจะเรียงลำดับตัวเองทันทีตามทิศทางที่ระบุโดยreverse
อาร์กิวเมนต์คำสำคัญดังที่แสดงการทดสอบต่อไปนี้:
import pytest
def test_1():
assert SortedList([5, 2, 3]) == [2, 3, 5]
def test_2():
SortedList([5, 2, 3], reverse=True) == [5, 3, 2]
def test_3():
with pytest.raises(TypeError):
sorted_list = SortedList([5, 2, 3], True) # This doesn't work because 'reverse' must be passed as a keyword argument
if __name__ == "__main__":
pytest.main([__file__])
ด้วยการส่งต่อ*args
ไปsuper
ยังรายการสามารถเริ่มต้นและเติมข้อมูลด้วยรายการแทนที่จะว่างเปล่า (โปรดทราบว่าreverse
เป็นอาร์กิวเมนต์คำหลักเท่านั้นตามPEP 3102 )
มีอีกวิธีหนึ่งในการสร้างคลาสย่อยใน python แบบไดนามิกด้วยฟังก์ชันtype()
:
SubClass = type('SubClass', (BaseClass,), {'set_x': set_x}) # Methods can be set, including __init__()
โดยปกติคุณต้องการใช้วิธีนี้เมื่อทำงานกับแว่นตา เมื่อคุณต้องการทำระบบอัตโนมัติระดับล่างนั่นจะเปลี่ยนวิธีที่ python สร้างคลาส เป็นไปได้มากว่าคุณไม่จำเป็นต้องทำด้วยวิธีนี้ แต่เมื่อคุณทำแล้วคุณจะรู้ว่ากำลังทำอะไรอยู่
class Subclass (SuperClass):
# Subclass stuff here
class Mammal(object):
#mammal stuff
class Dog(Mammal):
#doggie stuff
class BankAccount:
def __init__(self, balance=0):
self.balance = int(balance)
def checkBalance(self): ## Checking opening balance....
return self.balance
def deposit(self, deposit_amount=1000): ## takes in cash deposit amount and updates the balance accordingly.
self.deposit_amount = deposit_amount
self.balance += deposit_amount
return self.balance
def withdraw(self, withdraw_amount=500): ## takes in cash withdrawal amount and updates the balance accordingly
if self.balance < withdraw_amount: ## if amount is greater than balance return `"invalid transaction"`
return 'invalid transaction'
else:
self.balance -= withdraw_amount
return self.balance
class MinimumBalanceAccount(BankAccount): #subclass MinimumBalanceAccount of the BankAccount class
def __init__(self,balance=0, minimum_balance=500):
BankAccount.__init__(self, balance=0)
self.minimum_balance = minimum_balance
self.balance = balance - minimum_balance
#print "Subclass MinimumBalanceAccount of the BankAccount class created!"
def MinimumBalance(self):
return self.minimum_balance
c = BankAccount()
print(c.deposit(50))
print(c.withdraw(10))
b = MinimumBalanceAccount(100, 50)
print(b.deposit(50))
print(b.withdraw(10))
print(b.MinimumBalance())
Subclassing ใน Python ทำได้ดังนี้:
class WindowElement:
def print(self):
pass
class Button(WindowElement):
def print(self):
pass
นี่คือบทช่วยสอนเกี่ยวกับ Python ที่มีคลาสและคลาสย่อยด้วย