Python中的非虚拟继承

2 投票
3 回答
1967 浏览
提问于 2025-04-16 21:37

在Python中,是否可以实现非虚拟继承,还是说我必须使用组合的方式呢?

我想对每个子类的基类实例调用方法,而不是对所有子类共用一个基类实例。

更新示例:

  • 类A里面有一个列表。
  • 类B和类C是类A的子类。
  • B和C往A的列表里添加东西。
  • B和C的项目都在同一个A对象的单一列表中。
  • 我希望B和C各自有自己的A对象,因此也有各自的A.list。

3 个回答

0

B和C可以各自有自己的列表实例,但你必须在这些类的内部明确说明。看看这个例子:

class A(object):

    collection = [1, 2, 3]

    @classmethod
    def modify(cls):
        cls.collection.append('NICE!')


class B(A):

    collection = A.collection[:]


class C(A):

    collection = A.collection + [4, 5]


print A.collection
# [1, 2, 3]
print B.collection
# [1, 2, 3]
print C.collection
# [1, 2, 3, 4, 5]
B.modify()
C.modify()
print A.collection
# [1, 2, 3]
print B.collection
# [1, 2, 3, 'NICE!']
print C.collection
# [1, 2, 3, 4, 5, 'NICE!']
1

我们可以用一种简单的方式来理解Python和C++在处理类时的不同。C++中的每个类都是独立的,它定义了“实例成员变量的布局”,同时还会把一些元数据添加到一个表格中,这个表格会被C++的运行时用来确定方法的解析顺序。

而Python的工作方式则完全不同;在Python中,类本身并不定义属性的布局。当我们要创建一个类的实例时,运行时会把所有父类中定义的__slots__合并在一起,形成一个新的布局。

在C++中,类的定义决定了这些类是如何组合的,但在Python中,它们就像是混在一起的(但仍然是有条理的),所以在具体的实例层面上,你很难分清一个类的结束和下一个类的开始。这其实是因为Python对象本质上就是一堆属性的集合。

2

在Python中,如果一个基类被多次继承,那么不会有基类的单独实例。我觉得用继承的方式是无法实现你想要的效果的。不过,使用组合的方式应该可以正常工作。

顺便说一下,你的问题表述得有点复杂(用了C++的术语来问一个纯Python的问题),但我想我明白你的意思。如果我理解错了,抱歉哦。

撰写回答