Trong Python, làm cách nào để bạn tạo một lớp con từ lớp cha?
Trong Python, làm cách nào để bạn tạo một lớp con từ lớp cha?
Câu trả lời:
# Initialize using Parent
#
class MySubClass(MySuperClass):
def __init__(self):
MySuperClass.__init__(self)
Hoặc, thậm chí tốt hơn, việc sử dụng hàm tích hợp sẵn của Python, super()
(xem tài liệu Python 2 / Python 3 về nó) có thể là một phương pháp tốt hơn một chút để gọi hàm cha mẹ để khởi tạo:
# Better initialize using Parent (less redundant).
#
class MySubClassBetter(MySuperClass):
def __init__(self):
super(MySubClassBetter, self).__init__()
Hoặc, cùng một điều chính xác như trên, ngoại trừ việc sử dụng dạng đối số 0 super()
, chỉ hoạt động bên trong định nghĩa lớp:
class MySubClassBetter(MySuperClass):
def __init__(self):
super().__init__()
super
, đặc biệt là đối với các lập trình viên Python mới (ví dụ: Lutz). Tôi tránh nó.
super
là nếu bạn không hiểu sự khác biệt giữa cách super
hoạt động trong Python và cách super
/ parent
hoạt động trong các ngôn ngữ khác. Phải thừa nhận rằng điều này không rõ ràng đối với những người đến từ các ngôn ngữ khác, nhưng tôi sẽ không kết luận rằng điều đó đủ điều kiện để "thận trọng chống lại". Nó không làm việc. Nó chỉ hoạt động khác nhau. Chỉ cần đọc về những gì nó thực sự hoạt động trong Python trước khi bạn phàn nàn về việc nhận được kết quả mà bạn không mong đợi.
Một ví dụ nhỏ anh hùng:
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>
Các phần thừa kế trong tài liệu python giải thích nó một cách chi tiết hơn
__init__
phương thức đó nếu muốn thêm mã khác vào nó, nếu không, phương thức init gốc vẫn được sử dụng (mặc dù nó đáng được đề cập và là mã hoàn toàn hợp lệ)
Trong các câu trả lời ở trên, hàm super
được khởi tạo mà không có bất kỳ đối số (từ khóa) nào. Tuy nhiên, thông thường, bạn muốn làm điều đó, cũng như chuyển một số đối số 'tùy chỉnh' của riêng bạn. Đây là một ví dụ minh họa trường hợp sử dụng này:
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
Đây là một lớp con list
, khi được khởi tạo, ngay lập tức tự sắp xếp theo hướng được chỉ định bởi reverse
đối số từ khóa, như các thử nghiệm sau minh họa:
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__])
Nhờ việc chuyển *args
sang super
, danh sách có thể được khởi tạo và điền các mục thay vì chỉ để trống. (Lưu ý rằng đó reverse
là đối số chỉ từ khóa phù hợp với PEP 3102 ).
Có một cách khác để tạo động các lớp con trong python bằng một hàm type()
:
SubClass = type('SubClass', (BaseClass,), {'set_x': set_x}) # Methods can be set, including __init__()
Bạn thường muốn sử dụng phương pháp này khi làm việc với kính đo. Khi bạn muốn thực hiện một số tự động hóa cấp thấp hơn, điều đó sẽ thay đổi cách python tạo lớp. Nhiều khả năng bạn sẽ không cần phải làm theo cách này, nhưng khi bạn làm, bạn sẽ biết mình đang làm gì.
Bạn dùng:
class DerivedClassName(BaseClassName):
Để biết chi tiết, hãy xem tài liệu Python, phần 9.5 .
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())