【问题标题】:Python: How do I make a subclass from a superclass?Python:如何从超类创建子类?
【发布时间】:2010-12-09 02:53:49
【问题描述】:

在 Python 中,如何从超类创建子类?

【问题讨论】:

  • 请注意,Python 改变了您进行子类化的方式,因此有 2 种方式,它们不会混合使用。如果你混合,你会得到一个错误。阅读这篇文章以了解不同之处:stackoverflow.com/questions/1713038/…

标签: python class


【解决方案1】:

这是一个小代码:

# create a parent class

class Person(object):
    def __init__(self):
        pass

    def getclass(self):
        return 'I am a Person'
# create two subclass from Parent_class

class Student(Person):
    def __init__(self):
        super(Student, self).__init__()

    def getclass(self):
        return 'I am a student'


class Teacher(Person):
    def __init__(self):
        super(Teacher, self).__init__()

    def getclass(self):
        return 'I am a teacher'


person1 = Person()
print(person1.getclass())

student1 = Student()
print(student1.getclass())

teacher1 = Teacher()
print(teacher1.getclass())

显示结果:

I am a Person
I am a student
I am a teacher

【讨论】:

    【解决方案2】:
    # 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__()
    

    【讨论】:

    • OTOH,有些人告诫不要使用super,尤其是对于新的 Python 程序员(例如 Lutz)。我避免它。
    • 避免super 的唯一原因是如果您不了解super 在Python 中的工作方式与super/parent 在其他语言中的工作方式之间的区别。诚然,这对于来自其他语言的人来说并不明显,但我不会得出结论,这有资格将其视为“谨慎”。它确实工作。它只是工作方式不同。在抱怨得到意想不到的结果之前,请先了解它在 Python 中的实际作用。
    【解决方案3】:

    在上面的答案中,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】:
      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())
      

      【讨论】:

      • 如果您包含对它的作用的解释,这个答案会更有帮助
      • 虽然这段代码可能有助于解决问题,但它并没有解释为什么和/或如何回答问题。提供这种额外的背景将显着提高其长期教育价值。请edit您的答案添加解释,包括适用的限制和假设。
      • 虽然这段代码 sn-p 可以解决问题,including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
      【解决方案5】:
      class MySubClass(MySuperClass):
          def __init__(self):
              MySuperClass.__init__(self)
      
              # <the rest of your custom initialization code goes here>
      

      python 文档中的section on inheritance 更详细地解释了它

      【讨论】:

      • 如果要添加更多代码,您只需要定义__init__方法,否则无论如何都会使用原始的init方法(尽管值得一提,并且是完全有效的代码)
      • 我认为这个问题很模糊,可以假设可能会添加更多代码。最好提供太多信息而不是提供足够的信息,并在 OP 实施它时遇到另一个问题。 :)
      【解决方案6】:

      你使用:

      class DerivedClassName(BaseClassName):
      

      详情请见Python docs, section 9.5

      【讨论】:

        【解决方案7】:

        还有另一种方法可以使用函数type()在python中动态创建子类:

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

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

        【讨论】:

          【解决方案8】:

          一个英勇的小例子:

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

          【讨论】:

            【解决方案9】:

            Python 中的子类化如下:

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

            这是一个关于 Python 的tutorial,其中还包含类和子类。

            【讨论】:

              【解决方案10】:
              class Mammal(object): 
              #mammal stuff
              
              class Dog(Mammal): 
              #doggie stuff
              

              【讨论】:

                【解决方案11】:
                class Class1(object):
                    pass
                
                class Class2(Class1):
                    pass
                

                Class2 是 Class1 的子类

                【讨论】:

                • 酷。这就是我真正想要的,即没有扩展/覆盖超的子类。
                【解决方案12】:
                class Subclass (SuperClass):
                      # Subclass stuff here
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2019-06-28
                  • 2022-01-23
                  • 2016-05-07
                  • 2012-07-04
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-01-28
                  相关资源
                  最近更新 更多