以上就是给各位分享超级令人困惑的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 2.7 super()错误
- Python super()函数使用及多重继承
- Python super()传递* args
- Python super()参数:为什么不选择super(obj)?
超级令人困惑的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()错误
尝试使用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()函数使用及多重继承
super()函数可以用于继承父类的方法,语法如下:
super(type[, object-or-type])
虽然super()函数的使用比较简单,但是需要根据单继承和多继承来分析函数的调用关系。
首先,当类之间的继承关系为单继承时,函数调用关系也比较简单,可以参考如下的例子:
- #!/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采用广度优先(区别于深度优先)的规则定义。为了更好的理解这个问题,让我们先来看如下的代码:
- #!/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
传递*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()(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)?的相关知识,请在本站进行查询。
本文标签: