www.91084.com

GVKun编程网logo

超级令人困惑的python多重继承super()(python super多重继承)

39

以上就是给各位分享超级令人困惑的python多重继承super,其中也会对进行解释,同时本文还将给你拓展Python2.7super()错误、Pythonsuper()函数使用及多重继承、Python

以上就是给各位分享超级令人困惑的python多重继承super,其中也会对进行解释,同时本文还将给你拓展Python 2.7 super()错误、Python super()函数使用及多重继承、Python super()传递* args、Python super()参数:为什么不选择super(obj)?等相关知识,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

超级令人困惑的python多重继承super()(python super多重继承)

超级令人困惑的python多重继承super()(python super多重继承)

我在玩python中的多重继承,遇到了一个我无法理解它是如何发生的情况。

这是继承布局:

    A       F
  /   \     |
 B     C    |   
  \    |   /
    \  |  /   
       D

每个人都熟悉的ABCD钻石。再加上一个额外的“ F”类,我把它当作娱乐。

这是代码:

class A(object):
    def foo(self,call_from):
        print "foo from A,call from %s" % call_from
        super(A,self).foo("A")

class B(A):
    def foo(self,call_from):
        print "foo from B,call from %s" % call_from
        super(B,self).foo("B")

class C(A):
    def foo(self,call_from):
        print "foo from C,call from %s" % call_from
        super(C,self).foo("C")

class F(object):
    def foo(self,call_from):
        print "foo from F,call from %s" % call_from

class D(B,C,F):
    def foo(self):
        print "foo from D"
        super(D,self).foo("D")

输出:

>>> d = D()
>>> d.foo()
foo from D
foo from B,call from D
foo from C,call from B
foo from A,call from C
foo from F,call from A

方法解析顺序:

>>> D.__mro__
(<class '__main__.D'>,<class '__main__.B'>,<class '__main__.C'>,<class '__main__.A'>,<class '__main__.F'>,<type 'object'>)
  • foo from C,call from B 代替 foo from C,call from D
  • foo from F,call from A 只是把我赶走…

看起来好像super()是根据方法解析顺序链接在一起的,并且忽略了类之间的关系,但是我不确定。

有人可以指出我正确的方向来理解这种行为吗?

请记住,我正在尝试理解语言本身。不尝试解决实际问题。所以我没有用例。但是如果有人可以指出一个用例,那就太好了:)


更新:

总结-super()只是让您知道mro调用旁边的内容。不需要父母。尽管mro是基于继承层次结构构建的,但mro本身不是继承层次结构。

Python 2.7 super()错误

Python 2.7 super()错误

尝试使用super()创建Tkinter窗口。我收到此错误:

超级(应用程序,自我)。 _初始化 _(主)TypeError:必须为类型,而不是classobj

码:

import Tkinter as tkclass Application(tk.Frame):    def __init__(self, master):        super(Application, self).__init__(master)        self.grid()def main():    root = tk.Tk()    root.geometry(''200x150'')    app = Application(root)    root.mainloop()main()

答案1

小编典典

Tkinter使用老式的类。super()只能与新型类一起使用。

Python super()函数使用及多重继承

Python super()函数使用及多重继承

super()函数可以用于继承父类的方法,语法如下:

super(type[, object-or-type])

虽然super()函数的使用比较简单,但是需要根据单继承和多继承来分析函数的调用关系。

首先,当类之间的继承关系为单继承时,函数调用关系也比较简单,可以参考如下的例子:

  1. #!/usr/bin/env python3class A(object): def __init__(self): print('class A')class B(A): def __init__(self): super(B, self).__init__() print('class B')b = B()

上述代码运行结果如下:

class A
class B

从结果可以看出,子类B在实例化时调用了父类A的__init__()方法。

当进行多重继承时,需要考虑MRO的问题。所谓MRO,即Method Resolution Order,自Python2.3以来,MRO采用广度优先(区别于深度优先)的规则定义。为了更好的理解这个问题,让我们先来看如下的代码:

  1. #!/usr/bin/env python3class A(object): def __init__(self): self.n = 10 def minus(self, m): print('minus in class A start') self.n -= m print('minus in class A end')class B(A): def __init__(self): self.n = 7 def minus(self, m): print('minus in class B start') super(B, self).minus(m) self.n -= 2 print('minus in class B end')class C(A): def __init__(self): self.n = 12 def minus(self, m): print('minus in class C start') super(C, self).minus(m) self.n -= 5 print('minus in class C end')class D(B,C): def __init__(self): self.n = 15 def minus(self, m): print('minus in class D start') super(D, self).minus(m) self.n -= 2 print('minus in class D end')print('The MRO of class D is :')print(D.__mro__)d = D()d.minus(2)print(d.n)

代码运行结果:

The MRO of class D is :
(class ‘__main__.D’, class ‘__main__.B’, class ‘__main__.C’, class ‘__main__.A’, class ‘object’)
minus in class D start
minus in class B start
minus in class C start
minus in class A start
minus in class A end
minus in class C end
minus in class B end
minus in class D end
4

从运行结果可以看出,子类D的MRO为(class ‘__main__.D’, class ‘__main__.B’, class ‘__main__.C’, class ‘__main__.A’, class ‘object’),也就是子类D的minus函数在调用父类函数时的调用顺序依次为BCA,而后续的调试打印信息也正好验证了该顺序。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

Python super()传递* args

Python super()传递* args

传递*args意味着您可以像这样初始化Thief

>> x = Thief(True,False)
>> x.human
False
>> x.sneaky
True

这令人困惑,并且很难通过多重继承进行跟踪,但是它可能很有用。维持此功能意味着您可以做到

sneaky = (True,False,True,)
human = (True,)
thieves = [Thief(*args) for args in zip(sneaky,human)]

这有点做作,但是我认为这说明了为什么您可能希望允许位置参数。

如果您确实要删除*args并且不支持位置参数,则可以通过在{{1之后添加Sneaky来将它们从Person*,中排除}}。

self,

这不会将所有位置参数都放在未命名的class Sneaky: def __init__(self,*,sneaky=False,**kwargs): super().__init__(**kwargs) self.sneaky = sneaky class Person: def __init__(self,human=False,**kwargs): super().__init__(**kwargs) self.human = human 中。如果您尝试提供位置定位,则会产生*

,

在第一种情况下,以下代码将输出True

t = Thief(True,True)
print(t.human)
# True

但是在第二秒(没有*args)中-它将引发异常:

t = Thief(True,True)  # arguments without keywords
print(t.human)
# raises
# TypeError: __init__() takes 1 positional argument but 3 were given

Python super()参数:为什么不选择super(obj)?

Python super()参数:为什么不选择super(obj)?

我试图了解何时以及如何在Python中正确使用super()(2.7.x或3.x)

>>> help(super)翻译告诉我怎么称呼它:

class super(object) |  super(type) -> unbound super object |  super(type, obj) -> bound super object; requires isinstance(obj, type) |  super(type, type2) -> bound super object; requires issubclass(type2, type)

我了解在Python3.x中现在可以在类定义中使用super(),但是我不明白为什么super(obj)不可能。或super(self)在类定义中。

我知道一定有原因,但是我找不到。对我来说,这些行等于super(obj.__class__, obj)或,super(self.__class__,self)并且行得通吗?

我认为super(obj)即使在Python 3.x中,键入也是一个不错的快捷方式。

答案1

小编典典

仅在Python
2中才需要两个参数的形式。其原因是,它self.__class__总是引用继承树中的“叶子”类(即对象的最特定类),但是调用super时需要告诉它是当前正在调用的实现,因此它可以在继承树中调用下一个实现。

假设您有:

class A(object):   def foo(self):      passclass B(A):   def foo(self):      super(self.__class__, self).foo()class C(B):   def foo(self):      super(self.__class__, self).foo()c = C()

需要注意的是c.__class__C,始终。现在考虑如果您打电话给我会发生什么c.foo()

当您调用super(self.__class__, self)C的方法时,它将类似于call super(C,self),这意味着“调用C继承的此方法的版本”。那会叫B.foo,这很好。但是当您super(self.__class__,self)从B呼叫时,它仍然像在呼叫super(C,self),因为它是相同的self,所以self.__class__仍然如此C。结果是B中的调用将再次调用,B.foo并且发生无限递归。

当然,您真正想要的是能够调用super(classThatDefinedTheImplementationThatIsCurrentlyExecuting,self),这实际上就是Python 3super()所做的。

在Python 3中,您可以做,super().foo()并且可以做正确的事。对我来说,你对super(self)捷径的含义还不清楚。在Python
2中,由于上述原因,它不起作用。在Python 3中,这将是“ longcut”,因为您可以只使用Plain super()

super(type)super(type1, type2)用途可能仍然偶尔需要在Python 3,但那些总是不正常的情况下,更深奥的用途。

今天的关于超级令人困惑的python多重继承super的分享已经结束,谢谢您的关注,如果想了解更多关于Python 2.7 super()错误、Python super()函数使用及多重继承、Python super()传递* args、Python super()参数:为什么不选择super(obj)?的相关知识,请在本站进行查询。

本文标签: