Python:如何从超类中生成子类?


Answers:


89
# 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__()

6
OTOH,有些人警告不要这样做,super特别是对于新的Python程序员(例如Lutz)。我避免了。
eric 2015年

6
避免的唯一原因super是,如果您不了解superPython的工作方式与super/parent在其他语言中的工作方式之间的区别。诚然,这对于来自其他语言的人来说并不明显,但是我不会得出结论,这足以使它成为“警告”。它确实工作。它只是工作方式不同。在抱怨获得意想不到的结果之前,只需了解一下它在Python中的实际作用即可。
TheAtomicOption '17

3
两者有什么区别?
Tiwtiw


65

一个英雄的小例子:

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()

37
class MySubClass(MySuperClass):
    def __init__(self):
        MySuperClass.__init__(self)

        # <the rest of your custom initialization code goes here>

python文档中有关继承部分详细介绍了它


5
__init__如果要向其中添加更多代码,则只需要定义该方法,否则无论如何都要使用原始的init方法(尽管值得一提,并且是完全有效的代码)
dbr

2
我认为问题很模糊,以为可能还会添加更多代码。最好提供过多的信息而不是提供过多的信息,并在OP实施时遇到另一个问题。:)
马特·杜威

15
class Class1(object):
    pass

class Class2(Class1):
    pass

Class2是Class1的子类


凉。这就是我真正想要的,即没有扩展名的子类。
BuvinJ

9

在上述答案中,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__])

得益于传递的*argssuper,列表可以初始化和项目,而不是只为空填充。(请注意,这reverse是符合PEP 3102的仅关键字自变量)。


4

还有另一种方法可以通过python函数动态创建子类type()

SubClass = type('SubClass', (BaseClass,), {'set_x': set_x})  # Methods can be set, including __init__()

在使用元类时,通常需要使用此方法。当您想进行一些较低级别的自动化时,这会改变python创建类的方式。您很有可能永远不需要以这种方式进行操作,但是当您这样做时,您将已经知道自己在做什么。


3
class Subclass (SuperClass):
      # Subclass stuff here



1
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())

5
如果您包括对它的作用的解释,则此答案会更有用
凹槽复数

4
尽管此代码可能有助于解决问题,但并未解释为什么和/或如何回答问题。提供这种额外的环境将大大提高其长期教育价值。请编辑您的答案以添加解释,包括适用的限制和假设。
Toby Speight

2
尽管此代码段可以解决问题,但提供说明确实有助于提高您的帖子质量。请记住,您将来会为读者回答这个问题,而这些人可能不知道您提出代码建议的原因。
andreas

0

Python中的子类划分如下:

class WindowElement:
    def print(self):
        pass

class Button(WindowElement):
    def print(self):
        pass

这是有关Python的教程,其中也包含类和子类。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.