首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么在Python中,子类不能使用super调用父类方法

在Python中,子类不能使用super调用父类方法的原因是因为Python的多继承特性。当一个类有多个父类时,使用super调用父类方法可能会导致方法的调用顺序出现问题,从而引发意想不到的错误。

Python中的super函数用于调用父类的方法,它通过方法解析顺序(MRO)来确定调用哪个父类的方法。MRO是一个线性顺序列表,它定义了类继承的顺序。在多继承的情况下,MRO决定了方法的查找顺序。

当一个子类继承了多个父类时,使用super调用父类方法会按照MRO的顺序进行调用。如果子类中的某个父类没有被包含在MRO中,那么使用super调用父类方法时就无法找到正确的方法。

为了避免这种问题,Python建议使用显式调用父类的方法,即通过父类名来调用。这样可以明确指定要调用的父类方法,避免了MRO带来的不确定性。

举个例子,假设有以下代码:

代码语言:txt
复制
class A:
    def foo(self):
        print("A's foo")

class B(A):
    def foo(self):
        super().foo()
        print("B's foo")

class C(A):
    def foo(self):
        super().foo()
        print("C's foo")

class D(B, C):
    def foo(self):
        super().foo()
        print("D's foo")

d = D()
d.foo()

在这个例子中,类D继承了类B和类C,它们都继承了类A。如果在类D的foo方法中使用super调用父类方法,那么调用顺序将是B -> C -> A。最终的输出结果将是:

代码语言:txt
复制
A's foo
C's foo
B's foo
D's foo

可以看到,使用super调用父类方法时,按照MRO的顺序依次调用了父类的方法。

总结起来,Python中子类不能使用super调用父类方法是为了避免多继承带来的方法调用顺序不确定性。通过显式调用父类的方法,可以明确指定要调用的父类方法,避免了潜在的错误。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Python】面向对象 - 继承 ② ( 子类重写成员 | 子类调用重名成员 | 子类使用 调用成员 | 子类使用 super 调用成员 )

; 成员属性 重写 , 就是 子类 , 修改 成员属性的值 ; 成员方法 重写 , 就是 子类 , 修改 成员方法方法体内容 ; 子类 , 如果需要重写的成员 , 直接在子类 ,...重新定义父的成员即可 ; Python , 不像 Java / Kotlin / Groovy 一样 , 如果子类重写成员 , 需要使用 @Override 注解 修饰 ; 2、代码示例...: 名.成员方法名(self) 方法二 : 使用 super 调用成员 ; 调用类同名成员变量 : super().成员变量名 调用类同名成员方法 : super().成员方法名(...) 2、代码示例 - 子类使用 调用成员 Dog 子类的 make_sound 函数 , 通过 Animal.name 和 Animal.age 可以调用的成员变量 , 打印出来的值为的成员变量值...super 调用成员 Dog 子类的 make_sound 函数 , 通过 super().name 和 super().age 可以调用的成员变量 , 打印出来的值为的成员变量值

34430

Python实现子类调用方法

Person,但是并没有调用的__init__()方法,那么怎样调用方法呢?...调用一个实例的方法时,该方法的self参数会被自动绑定到实例上(称为绑定方法)。但如果直接调用方法(比如Person.__init__()),那么就没有实例会被绑定。...通过将当前的实例作为self参数提供给未绑定方法,Student就能使用其父构造方法的所有实现,从而name变量被设置。...函数会返回一个super对象,这个对象负责进行方法解析,解析过程其会自动查找所有的以及。...方法一更直观,方法二可以一次初始化所有超. super函数比超累中直接调用未绑定方法更直观,但是其最大的有点是如果子类继承了多个,它只需要使用一次super函数就可以。

3.1K10

【Kotlin】Kotlin 的继承 三 ( super 关键字使用 | super@ 外部调用方法 | 子类选择性调用 接口 方法 super )

子类重写方法 : 如果属性 或 方法子类重写了 , 那么就需要使用 super 关键字调用类属性或方法 ; 4 . super 关键字调用需要考虑的情况 : ① 常用情况 : 最常用的情况只使用...super 关键字进行简单调用即可 ; ② 子类内部类调用 : 如果想要在子类的内部调用的成员和方法 , 需要使用 super@子类名称 调用 ; ③ 子类调用不同父的同名方法 : 如果子类继承的...子类调用方法 ( super ) ---- 子类调用方法 : 子类可以通过 super 调用方法 , 包括普通方法 , 和属性访问的 setter 方法 ; 其中的 super 相当于对象的引用...子类内部类调用方法 ( super@ ) ---- 子类内部类调用方法 : 子类的内部类 , 如果想要访问方法 , 可以使用 super@子类名称.方法() 的形式 , 调用方法...代码示例 : 代码定义了一个 Father , 接口 Build , 和接口 都定义了 action 方法 , 子类 Son 继承 , 实现 Build 接口 , 子类通过 super 调用的成员或方法

1.1K10

Python_子类调用方法

1.方式一 子类调用方法,包含2形式的调用。一种形式是内部通过继承的方式调用方法,另外一种形式是子类实例化后之后通过继承的方式来调用方法。如下图所示: ?...3班") #调用子类本身的方法 student.course() #通过子类调用方法--->实例化之后来调用方法 student.eat() #调用子类方法子类方法调用子类方法,...使用super的好处,一是可以代替父名,这样后期名更改了,我们只需要更改子类名称后面的名即可,子类其他的名可以不用更改;二是使用super后,调用方法时可以不传参数self。...__init__(self,name,age,sex) #通过子类把参数传给(self不能少,self只有实例化和实例调用时才能省略,此处不是) #使用super来替换名...#子类调用方法 super().eat() #子类调用方法,使用super可以省略self #实例化一个子类 student = Student("周明",23,'男',

4.8K20

Python 子类调用方法详解(单继承、多层继承、多重继承)

测试环境: win7 64位 Python版本:Python 3.3.5 代码实践: 1、子类通过“名”调用方法 class FatherA: def __init__(self)...__init__(self) # 子类调用方法名.方法名称(参数) if __name__ == '__main__': b = SubClassB() 运行结果: >>> ==...(如SubClassB的由FatherA变为FatherD时),必须遍历整个定义,把子类中所有的名全部替换过来 2、子类通过“super方法调用方法 场景1、单层继承 class...__init__() # 子类调用方法super().方法名称(参数) if __name__ == '__main__': b = SubClassB() class FatherA...__init__() # 子类调用方法super(type, obj).方法名称(参数) if __name__ == '__main__': b = SubClassB() 运行结果

2.9K30

python调用方法的三种方式(super调用调用

子类调用方法的三种方式:名.方法名(self)super(子类名,self).方法名()super().方法名注意:super()通过子类调用当前方法super默认会调用第一个方法...默认会调用第一个方法(适用于单继承 或者只想使用第一个方法) # 02 方式 适用于新式 # 格式: super(子类名, self).方法名()...针对这种情况,正确的做法是定义Person自己的构造方法(等同于重写第一个直接的构造方法),但是需要注意的是,子类定义构造方法,则必须在该方法调用的构造方法。...未绑定方式使用super()函数,但如果涉及多继承,该函数只能调用第一个直接的构造方法。...也就是说,涉及到多继承时,子类构造函数调用第一个构造方法的方式有以上两种,而调用其他构造方法的方式只能使用未绑定方法

1.1K20

创建子类对象时,构造函数调用子类重写的方法为什么调用的是子类方法

A对象的时候调用子类方法?...但是:创建B对象调用方法? 答案: 当子类被加载到内存方法区后,会继续加载到内存。...如果,子类重写了方法子类方法引用会指向子类方法,否则子类方法引用会指向方法引用。 如果子类重载了方法,则子类重载方法引用还指向子类方法。...如果子类方法没有重写也没有重载方法,则方法引用会指向方法。 当子类对象创建时,会先行调用的构造方法(构造方法也是方法),虚拟机会在子类方法区寻找该方法并运行。...其结果是当编译的时候,构造方法调用方法的参数已经强制转换为符合方法的参数了。 上边代码在编译前已经转换为下面这个样子的了。

6.1K10

python子类调用的初始化方法

如果一个方法子类的实例中被调用,或者一个属性子类的实例中被访问,但是该方法或属性子类并不存在,那么就会自动的去其父中进行查找。...继承后,就能调用方法和访问类属性,而要完成整个集成过程,子类是需要调用的构造函数的。...子类不显式调用的构造方法,而构造函数初始化了一些属性,就会出现问题 如果子类都有构造函数,子类其实是重写了的构造函数,如果不显式调用构造函数,的构造函数就不会被执行,导致子类实例访问初始化方法初始的变量就会出现问题...方法一更直观,方法二可以一次初始化所有超 super函数比超累中直接调用未绑定方法更直观,但是其最大的有点是如果子类继承了多个,它只需要使用一次super函数就可以。...二、第二种解释     Python子类继承的过程,如果子类不覆盖的__init__()方法,则子类默认将执行与一样的初始化方法

2.1K10

再谈包访问权限 子类为何不能使用protected方法

方法 并且觉得很奇怪,并且认为  子类不同包不能访问的protected方法 其实这是概念错了 虽然是子类,但是却是使用的对象,调用的protected方法 这是不同包,访问protected...方法 当然是错误的   protected的含义是指子类可以访问,说的是子类直接访问的protected方法 而不是说子类,可以调用的对象访问的protected方法 子类可以访问,可以子类访问不是一个概念...默认的包访问权限 同一个包,不管其他条件,管你是不是子类都没关系的,不要自己去混淆 protected 就是默认的包访问权限扩展了一下,  子类对象可以访问,不管是不是同一个包,而不是子类中用对象访问...,子类可以使用 子类继承了的protected方法,所以子类有这个方法,所以子类可以使用,但是子类不能读取某个对象的保护方法的(包外) 继承是继承的结构,跟任何具体的对象的数据没关系,所以子类不能创建的对象然后调用的...protected方法,不能在包外访问protected方法 但是如果方法是protected static的,可以子类创建对象然后调用方法 因为子类是继承的的,着重点在于,继承了的成员

1.7K30

关于使用MethodHandle子类调用祖父重写方法的探究

关于使用MethodHandle子类调用祖父重写方法的探究 注:这个例子原本出现在周志明先生的《深入理解Java虚拟机》--虚拟机字节码执行引擎章节,介于有读者朋友有疑问,这里基于Java代码层面解释一下...这里直接看Son的thinking方法(关于为何这样实现,《深入理解Java虚拟机》读书笔记(七)--虚拟机字节码执行引擎(下)也解释了)。...普通的方法调用,这个this参数是虚拟机自动处理的,表示的是当前实例对象,我们方法可以直接使用。...我觉得使用bindTo绑定方法接收者要比invoke方法传递更加友好,也更加符合程序员的大众理解,invoke可以只专注方法显式的入参。 然后再来说bindTo(this)的this。...基于这个事实,我们这时可以直接在GrandFather的thinking方法调用Son独有的方法使用反射或者直接类型强制转换为Son就行了。

9.4K30

为什么静态方法不能使用this

JVM的运行时数据区中有个虚拟机栈(或Java栈),它的里面是由栈帧'叠加'而成.栈帧由局部变量表,操作数栈,动态连接,方法返回地址等组成. 那么我们就从局部变量表角度解答下这个问题....下面是测试代码,一个静态方法query,一个普通方法shadow,这两个方法的参数和函数体完全一样. // 静态方法 public static void query(String year) {...int month = 12; String address = "Jiangsu"; System.out.println(address); } // 普通方法 public void...query方法的局部变量表,如下 shadow方法的局部变量表,如下 我们发现,非静态方法shadow的局部变量表中有this,而在静态方法query的局部变量表没有this....普通方法,它的局部变量表的第一个槽存放了this, 而静态方法的局部变量表没有存放this.

1.9K30

Python通过对象不能调用方法和静态方法的解析

当我们使用Python编写程序时,可能会遇到通过对象调用方法和静态方法失败的问题,那么这是为什么呢?接下来,我们将从多个方面对这个问题进行详细解析。...一、方法和静态方法的定义了解Python通过对象不能调用方法和静态方法之前,首先需要明确方法和静态方法的定义。...方法和静态方法都是定义的一种方法,可以通过名直接调用,而不需要先创建该类的实例。...二、对象调用方法的原理Python,对象调用方法的原理可以简单概括为:Python通过找到方法所在的,并将该对象作为第一个参数(通常用self)传入方法。...三、不能通过对象调用方法和静态方法的原因既然Python对象调用方法的原理是将该对象作为第一个参数传入方法,那么为什么不能通过对象调用方法和静态方法呢?

59630

关于Java构造函数(Constructor)的常见问题总结1 为什么调用子类的构造方法的时候,默认会调用的构造方法2 常见错误:Implicit super constructor is und

1 为什么调用子类的构造方法的时候,默认会调用的构造方法 看下面这个简单的例子: package cc; public class Sub extends Super { public Sub...这就是为什么我们上面的那个例子程序会先调用super的构造方法。 但要切记,** 虽然调用的构造方法,但只创建了一个对象也就是子对象。...上一小节,我们知道,如果子类的构造函数,没有显示的调用的构造函数,那么,编译器就会插入super(),也就是自动调用无参的构造函数。但是此时,没有无参的构造函数,所以就会报错了。...解决这个问题很简单,我们可以给插入一个无参的构造函数,或者子类构造函数显示的调用有参构造函数。 子类的构造函数显示的调用的构造函数 下面的代码是正确的。 ?...Paste_Image.png 构造函数的使用规则 简单的说,使用的时候,子类的构造函数必须调用的构造函数,不管有没有显示的声明。所以,被调用构造函数,一定在定义好!

2.5K30

python子类继承时进行初始化的一些问题

这是为什么呢? __init__相当于是python的构造方法进行实例化时被调用,当子类中都存在构造方法时,子类需要显示调用的构造方法 。...需要注意的是python构造方法不能进行重载的,当有多个构造方法存在时,会默认调用最后一个构造方法。...super(Student, self).__init__():其中super关键字表示,Student是本类的名称,self指代本类自己。 python如何设置私有属性和方法?...将属性和方法前面加上__(双下划线)。加上了私有的属性和方法不能外进行访问,同时,子类继承的属性和方法时,子类不能够访问的私有属性和方法。...print("子类使用的共有属性:",self.age) #super()代表,可以访问的公有方法 #当然如若子类没有重写方法,也可以使用self.test

58050

Python多继承、super与MRO算法

但有时需要在B中直接访问A的成员,也就是子类需要调用的成员,在这种情况下,有如下两种方法可以解决: 1. 子类中直接通过名访问的成员 2....子类通过super访问的成员 现在先说第一种方法。...2.引入super 为了尽可能避免子类中直接使用的名字,从Python2.2开始支持supersuper并不是一个函数或方法,而是一个。...可能有的同学会问,super的第2个参数的值为什么是self呢?我们都知道,Python,self表示本身的实例,那么为什么不是B()或是A()呢?...但这里有一个问题,如果在MyClass2调用D的构造方法MyClass1调用A的构造方法,该怎么办呢?当然,可以直接使用名进行调用,那么使用super应该如何调用

49210

Python super()方法、多继承以及MRO顺序

仅供学习,转载请注明出处 单独调用方法 需求:编写一个,然后再写一个子类进行继承,使用子类调用方法1。 使用方法1打印: 胖子老板,来包槟榔。...super 是用来解决多重继承问题的,直接用调用方法使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。...方法,对的传参数,应该是由于pythonsuper的算法导致的原因,必须把参数全部传递,否则会报错 单继承时,使用super方法,则不能全部传递,只能传方法所需的参数,否则会报错 多继承时,相对于使用名...为什么改变了 Parent.x 的值还会改变 Child2.x 的值,但是同时 Child1.x 值却没有改变? 这个答案的关键是, Python 变量在内部是作为字典处理的。...因此,设置 x = 1 会使得变量 x 引用该类和其任何子类的值为 1。这就是因为第一个 print 语句的输出是 1 1 1。

1.5K30

python面向对象的继承-组合-02

:# 继承的一方可以直接使用被继承一方已经有的东西 程序,继承描述的是之间的关系 ​ 例如:a继承了b,a就能直接使用b已经存在的方法和属性 ​ 此时,a称之为子类,b称之为,也称之为基...为什么使用继承:# 其目的是为了重用已经有了的代码,提高重用性 如何使用继承 语法 class 名称(的名称): # python 一个子类可以同时继承多个 继承小案例(子类直接用方法...练习:实现一个可以限制元素类型的容器(子类访问的内容) 补充知识点 ​ 子类访问方法:# super(当前名称, self).你要调用的属性或方法 # 小练习:做一个可以限制元素类型的容器类型...的新语法 ***** (推荐,python2项目慎用哦) # 3..属性/方法 没啥实际意义,不是继承,这是直接用调用了 代码案例 # 子类访问的属性 class Parent:...__init__(name, gender, age) # 不调用的__init__方法就会使的初始化函数的say_hello方法,初始化就不能算是完成 *** self.number

53930
领券