在C/C++中,当且仅当被调用函数对调用者可见时,调用函数才能调用被调用函数,这意味着被调用者的定义应该在它被使用之前完成,否则使用forward-declaration.
这是我的问题,
class A
{
public:
void foo()
{
bar();
}
void bar()
{
//...
}
};
int main()
{
A a;
a.foo();
}
Run Code Online (Sandbox Code Playgroud)
上面的代码可以正常工作.但foo电话bar和我没有把bar的定义之前foo或前瞻性声明bar,怎么可能调用bar的foo工作?编译器怎么能找到bar?
有很多很棒的资源super(),包括这篇很棒的博客文章,以及关于Stack Overflow的很多问题.但是我觉得他们都没有解释它在最常见的情况下是如何工作的(使用任意继承图),以及在幕后发生的事情.
考虑这个钻石继承的基本例子:
class A(object):
def foo(self):
print 'A foo'
class B(A):
def foo(self):
print 'B foo before'
super(B, self).foo()
print 'B foo after'
class C(A):
def foo(self):
print 'C foo before'
super(C, self).foo()
print 'C foo after'
class D(B, C):
def foo(self):
print 'D foo before'
super(D, self).foo()
print 'D foo after'
Run Code Online (Sandbox Code Playgroud)
如果从像源Python的规则,方法解析顺序读了这个或查找的维基百科页面的C3线性化,你会看到,MRO必须(D, B, C, A, object).这当然得到以下证实D.__mro__:
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>) …Run Code Online (Sandbox Code Playgroud) python oop multiple-inheritance super method-resolution-order
在Python 网页上的文档中,python中经典类的方法解析顺序被描述为深度优先从左到右搜索。我试图用这段代码来测试这个:
class A(object):
def __init__(self):
print "Initialized A"
class B(A):
def test():
print "Initialized B"
class C(A):
def __init__(self):
print "Initialized C"
class D(B, C):
def __init__(self):
super(D, self).__init__()
print "Initialized D"
Run Code Online (Sandbox Code Playgroud)
当我创建对象 D 的实例时:
D()
Run Code Online (Sandbox Code Playgroud)
我得到结果:
Initialized C
Initialized D
Run Code Online (Sandbox Code Playgroud)
虽然我期望打印“初始化 A”、“初始化 D”,因为 MRO 是深度优先的,但首先在 B 中搜索初始化,如果找不到(就是这种情况),它应该在层次结构中更深入并查找B(即A)的基类中的函数。有人能解释一下为什么我得到 C 的 init 函数而不是 A 的那个吗?
为什么元类没有出现在MRO中?
例如:
>>> class Foo(type):
... foo = 21
...
>>> class Bar(metaclass=Foo):
... pass
...
>>> Bar.mro()
[<class '__main__.Bar'>, <class 'object'>]
>>> Bar.foo
21
Run Code Online (Sandbox Code Playgroud)
另外,我在其他地方看到Python使用C3线性化来计算MRO,但是这种线性化不处理元类.那么Python在这种情况下使用什么算法呢?
class Root(object):
def draw(self):
# the delegation chain stops here
assert not hasattr(super(Root, self), 'draw')
class Shape(Root):
def __init__(self, shapename, **kwds):
self.shapename = shapename
super(Shape, self).__init__(**kwds)
def draw(self):
print 'Drawing. Setting shape to:', self.shapename
super(Shape, self).draw()
class ColoredShape(Shape):
def __init__(self, color, **kwds):
self.color = color
super(ColoredShape, self).__init__(**kwds)
def draw(self):
print 'Drawing. Setting color to:', self.color
super(ColoredShape, self).draw()
# ------- Show how to incorporate a non-cooperative class --------
class Moveable(object):
# non-cooperative class that doesn't use super()
def __init__(self, …Run Code Online (Sandbox Code Playgroud) 我对某些 Python 类中的多重继承的设计有一些疑问。
问题是我想扩展 ttk 按钮。这是我最初的建议(我省略了缩短方法中的所有源代码,除了init方法):
import tkinter as tk
import tkinter.ttk as ttk
class ImgButton(ttk.Button):
"""
This has all the behaviour for a button which has an image
"""
def __init__(self, master=None, **kw):
super().__init__(master, **kw)
self._img = kw.get('image')
def change_color(self, __=None):
"""
Changes the color of this widget randomly
:param __: the event, which is no needed
"""
pass
def get_style_name(self):
"""
Returns the specific style name applied for this widget
:return: the style name as a …Run Code Online (Sandbox Code Playgroud) tkinter multiple-inheritance ttk method-resolution-order python-3.x
以下程序可以成功运行:
class Simple(object):
def __init__(self, name):
self.name = name
def __add__(self, other):
c = Composite()
c._members.append(self)
c._members.append(other)
return c
def __repr__(self):
return "Simple('%s')" % self.name
class Composite(object):
def __init__(self):
self._members = []
def __add__(self, obj):
if isinstance(obj, Simple):
out = Composite()
out._members = [k for k in self._members] + [obj]
elif isinstance(obj, Composite):
out = Composite()
out._members = [k for k in self._members + obj._members]
else:
raise TypeError
return out
if __name__ == "__main__":
s1 = Simple('one')
s2 = Simple('two') …Run Code Online (Sandbox Code Playgroud) python class-design forward-declaration method-resolution-order
我希望能够打电话给'person.Person.类 "并取回'类person.Person’,像它用于一个Person对象:
>>> p = person.Person()
>>> p.__class__
<class 'person.Person'>
>>> person.Person.__class__
<class 'perframe.datatype.TypeSystemMeta'>
Run Code Online (Sandbox Code Playgroud)
这是Person继承树......
class TypeSystem(object):
__metaclass__ = TypeSystemMeta
class Model(TypeSystem):
pass
class Node(Vertex,Model):
pass
class Person(Node):
pass
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?
python reflection inheritance multiple-inheritance method-resolution-order
我有一个继承的类并覆盖了一个也从基类继承的方法.但问题是中间方法创建了一个异常,我想通过调用第一个声明的方法来绕过它.有没有办法指定忽略第二次调用的mro?
一个例子可能是:
class Base(object):
def __init__(self):
res = "Want this"
print res
class BaseA(Base):
def __init__(self):
res = super(BaseA, self).__init__()
res = "Not this"
print res
class BaseB(BaseA):
def __init__(self):
res = super(BaseB, self).__init()
#At this poing res is "Not this"
#The desire is that it would be "Want this"
print res
Run Code Online (Sandbox Code Playgroud)
非常感谢
PD:像BaseB(Base,BaseA)这样的东西可以工作吗?
using System;
using System.Collections.Generic;
namespace Generics
{
class Minivan
{
public void foo(int z, int x)
{
Console.WriteLine("foo with two parameters");
}
public void foo(params int[] z)
{
Console.WriteLine("foo with two params parameter");
}
}
class D
{
public static void Main()
{
Minivan car3 = new Minivan();
car3.foo(10,20); // which method will be called here!!!
}
}
}
Run Code Online (Sandbox Code Playgroud)
哪个foo方法被调用?为什么?
python ×7
inheritance ×2
super ×2
.net ×1
c# ×1
c++ ×1
class-design ×1
metaclass ×1
oop ×1
params ×1
python-2.7 ×1
python-3.x ×1
reflection ×1
tkinter ×1
ttk ×1