在 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中super
的工作方式与其他语言中super
/parent
的工作方式之间的区别。必须承认,对于来自其他语言的人来说,这并不明显,但我不会认为这就足以提醒他们"小心使用"。它确实能够使用,只是有所不同。在抱怨得到意料之外的结果之前,请先阅读一下它在Python中实际做了什么。 - TheAtomicOption__init__
参数相同的示例。 - spatialaustin一个英勇的小例子:
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>
Python文档中关于继承的部分有更详细的解释。
__init__
方法,否则将继续使用原始的init
方法(尽管值得一提,这是完全有效的代码)。 - dbrclass 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())