在Python中,如何从超类中生成子类?
Answers:
# 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()
在上述答案中,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的仅关键字自变量)。
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())