为什么我们在python的子类中使用super()方法

2024-10-01 17:42:20 发布

您现在位置:Python中文网/ 问答频道 /正文

因此,在python中,要在子类中调用父类函数,我们使用super()方法,但是当我们可以调用父类函数时,为什么我们要使用super()方法呢?假设我有一个Class Employee:,并且我有另一个从Employee类class Programmer(Employee):继承的类要调用程序员类中Employee类的任何函数,我只需使用Employee.functionName()即可。 下面是一些代码:

class Person:
    country = "India"

    def takeBreath(self):
        print("I am breathing...")

class Employee(Person):
    company = "Honda"

    def getSalary(self):
        print(f"Salary is {self.salary}")
    
    def takeBreath(self):
        print("I am an Employee so I am luckily breathing...")

class Programmer(Employee):
    company = "Fiverr"

    def getSalary(self):
        print(f"No salary to programmer's.")
    
    def takeBreath(self):
        Employee().takeBreath()
        print("I am a Programmer so i am breathing++..")

p = Person()
p.takeBreath()

e = Employee()
e.takeBreath()

pr = Programmer()
pr.takeBreath()

正如您所看到的,我想在Programmer()类中调用Employee functionstakeBreath()方法,所以我刚刚编写了Employee.takeBreath(),它也可以完成这项工作,所以有人能解释一下为什么我们需要python中的super()方法吗

:)


Tags: 方法函数selfdefemployeeamcompanyclass
3条回答

您已经得到了一些关于为什么代码不起作用的答案(您正在创建一个新的Employee,而不是用自己的self调用Employee的方法),以及为什么通过super进行委托很方便(如果您更新父类,则不必更新所有代码)

另一个原因是Python支持多重继承,显式委托根本无法与菱形继承模式一起工作

菱形图案是这样的:

    A
   / \
  /   \
 B     C
  \   /
   \ /
    D
class A:
    def foo(self):
        ...
class B(A):
    def foo(self):
        ...
class C(A):
    def foo(self):
        ...
class D(C, B):
    def foo(self):
        ...

“D”扩展了“B”和“C”,还覆盖了“foo”以添加自己的内容。“D”不能只调用“B::foo”和“C::foo”:如果它这样做,那么两个都会依次调用“A::foo”,如果它有危险的副作用,则会调用两次

如果您使用super(),那么Python将使用方法解析顺序(特别是C3)管理链:创建类时,它将生成所有父类的线性序列,调用super()时,它只需从该序列开始遍历,以找到“父”方法,甚至在完全不相关的类之间

这里的MRO是D->;C->;B->;A、 因此,当D调用super().foo()时,Python将调用C::foo,其超级将调用B::foo*尽管C和B彼此不了解

使用super(),您不需要在从Person()类继承的每个类中定义takeBreath()

super()是一种更为通用的方法。假设您决定更改超类。也许你把它命名为Tom,而不是Employee。现在你必须去改变你电话中提到的每一件事

您可以将super()视为获取超类的“代理”,而不管它是什么。它使您能够编写更灵活的代码

不过,你所做的是不同的。每次都要创建Employee的一个新实例,然后对其调用该方法。如果将takeBreath方法更改为不接受self参数,则可以执行类似Employee.takeBreath()或更好的操作super().takeBreath()

相关问题 更多 >

    热门问题