Python如何通过多重继承传递__init__参数 [英] How does Python pass __init__ parameters with multiple inheritance
问题描述
我有以下代码,显示了经典的菱形图案:
I have this code, showing a classic diamond pattern:
class A:
def __init__( self, x ):
print( "A:" + x )
class B( A ):
def __init__( self, x ):
print( "B:" + x )
super().__init__( "b" )
class C( A ):
def __init__( self, x ):
print( "C:" + x )
super().__init__( "c" )
class D( B, C ):
def __init__( self ):
super().__init__( "d" )
d = D()
输出为:
B:d
C:b
A:c
-
B:d
很有意义,因为D
源自B
. - 我几乎得到了
A:c
,尽管我同样可以看到A:b
. - 但是,
C:b
位没有任何意义:C
不是从B
派生的. B:d
makes sense, sinceD
derives fromB
.- The
A:c
I almost get, though I could equally seeA:b
. - However, the
C:b
bit doesn't make sense:C
does not derive fromB
.
有人可以解释吗?
不幸的是,诸如此之类的问题没有提及参数.
Questions such as this unfortunately do not mention the parameters.
推荐答案
Python中的类是动态组合的-包括继承.
Classes in Python are dynamically composed - that includes inheritance.
C:b
输出并不意味着B
神奇地继承自C
.如果您实例化B
或C
,则彼此都不知道.
The C:b
output does not imply that B
magically inherits from C
. If you instantiate either B
or C
, none knows about the other.
>>> B('root')
B:root
A:b
但是,D
知道B
和C
:
class D(B,C):
...
有很多技术.但是,其工作原理基本上由两部分组成:
There is a lot of technicalities available on this. However, there are basically two parts in how this works:
- 直接基类按顺序显示.
-
B
在C
之前.
-
- Direct Base Classes are resolved in order they appear.
B
comes beforeC
.
-
B
和C
的基类必须都遵循.
- A Base Class of both
B
andC
must follow both.
对于类D
,这意味着基类解析为B->C->A
! C
潜入了B
和A
之间-但仅适用于类D
,而不适用于类B
.
For the class D
, that means the base classes resolve as B->C->A
! C
has sneaked in between B
and A
- but only for class D
, not for class B
.
请注意,实际上还涉及另一个 类:默认情况下,所有类均源自object
.
Note that there is actually another class involved: all classes derive from object
by default.
>>> D.__mro__
(__main__.D, __main__.B, __main__.C, __main__.A, object)
您已经写了A
,知道没有任何依据可以接受其参数.但是,B
和C
都不能假定这一点.他们都希望从A
对象派生.子类化确实暗示B
和C
也是有效的A
对象,但是!
You have already written A
knowing that there is no base to take its parameters. However, neither B
nor C
can assume this. They both expect to derive from an A
object. Subclassing does imply that both B
and C
are valid A
-objects as well, though!
B
和 C
在B
和 C
之前均有效 A
的子类. B->C->A->object
不会破坏B
期望其超类为A
类型.
It is valid for both B
and C
to precede B
and C
, since the two are subclasses of A
. B->C->A->object
does not break that B
expects its super class to be of type A
.
对于所有其他组合,最后以C
在任何内容之前(无效)或object
在某些内容之前(无效)结束.排除了深度优先分辨率B->A->object->C
并复制了B->A->object->C->A->object
.
With all other combinations, one ends up with C
preceding nothing (invalid) or object
preceding something (invalid). That rules out depth-first resolution B->A->object->C
and duplicates B->A->object->C->A->object
.
此方法解析顺序对于启用 mixins :依赖其他类来定义方法解析方式的类很实用.
This method resolution order is practical to enable mixins: classes that rely on other classes to define how methods are resolved.
很好的例子字典访问记录器可以接受dict
和OrderedDict
.
There is a nice example of how a logger for dictionary access can accept both dict
and OrderedDict
.
# basic Logger working on ``dict``
class LoggingDict(dict):
def __setitem__(self, key, value):
logging.info('Settingto %r' % (key, value))
super().__setitem__(key, value)
# mixin of different ``dict`` subclass
class LoggingOD(LoggingDict, collections.OrderedDict):
pass
这篇关于Python如何通过多重继承传递__init__参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!