在 Python 中从具有多重继承的右父类调用函数

问题描述 投票:0回答:1

我有两个类

A
B
并且都有一个方法
get_type()
返回一个字符串,并且在两个类的
__init__()
中调用它来设置实例属性
self.type
。现在有一个继承自
A
B
的子类,在它的
__init__()
中,它需要一个
A
B
的实例作为参数。根据它是用
A
还是
B
的实例实例化,我调用相应的父级
__init__()
。大概是因为多重继承的查找顺序,总是调用
get_type()
父级的
A
方法,即使
C
是用
B
的实例实例化的。见以下代码:

class A:
    def __init__(self):
        self.type = self.get_type()
    def get_type(self):
        return 'A'
class B: 
    def __init__(self):
        self.type = self.get_type()
    def get_type(self):
        return 'B'
class C(A, B):
    def __init__(self, instance):
        if isinstance(instance, A):
            A.__init__(self)
            print('Inheriting from A')
        else:
            B.__init__(self)
            print('Inheriting from B')
            
a = A()
b = B()
c = C(b)
print(a.type, b.type, c.type)

>>> Inheriting from B
>>> A B A

所以我希望

c.type
是“B”,因为它继承自
B
类。我可以使用
super()
函数来获得我想要的行为吗?

python python-3.x class inheritance multiple-inheritance
1个回答
0
投票

为什么你分开做那件事,这就是你要的:

当您有冲突(或潜在冲突)的方法名称时,Python 的避免机制是在方法名称前加上两个下划线 (

__
)。大多数关于 Python 的文章和第 3 方文档都将此称为“在 Python 中创建私有属性/方法的方法”。事实并非如此:Python 根本不使用私有属性,而是为了约定(使用单个
_
作为前缀。

使用两个下划线而不是一个下划线,触发方法或属性的内部名称转换,以透明的方式将类名作为前缀添加到目标方法。这称为“名称修改”。

就您的代码而言,它将开箱即用,无需进一步更改。如果您检查正在运行的代码(例如

print(dir(self))
),您将看到您的方法将分别命名为
A._A__get_type
B._B__get_type
(这两种方法都将出现在
C
中)

class A:
    def __init__(self):
        self.type = self.__get_type()
    def __get_type(self):
        return 'A'
class B: 
    def __init__(self):
        self.type = self.__get_type()
    def __get_type(self):
        return 'B'

但是,看到

C
中的任何方法都无法“看到”
.get_type
:该方法现在对每个超类都是“私有的”。两者都可以从 C 访问它们的转换名称,如果明确使用,很难。

© www.soinside.com 2019 - 2024. All rights reserved.