Не виртуальное наследование в Python - PullRequest
2 голосов
/ 15 июля 2011

Возможно ли не-виртуальное наследование в Python или мне нужно использовать композицию?

Я хотел бы вызывать методы для отдельного экземпляра базового класса для каждого подкласса, а не для одного подкласса для всех подклассов.

Пример обновления:

  • У класса А. есть список.
  • Класс B и C являются подклассами A
  • B и C добавляют вещи в список A.
  • Элементы B и C находятся в одном списке в одном объекте A.
  • Я хочу, чтобы у B и C был свой собственный A и, следовательно, собственный список A.

Ответы [ 3 ]

2 голосов
/ 15 июля 2011

В Python нет отдельного экземпляра базового класса, если базовый класс наследуется несколько раз.Я не верю, что с помощью наследования можно достичь того, что вы просите.Композиция должна работать нормально.

PS Ваш вопрос сформулирован довольно загадочно (используя терминологию C ++ для чисто Python-вопроса), но я думаю, что понял.Если я не сделал, мои извинения.

1 голос
/ 15 июля 2011

Один из способов понять, как python по-разному относится к классам, - это то, что каждый язык делает с классом. В C ++ каждый класс сам по себе является определением «макета переменных-членов экземпляров», а также добавляет некоторые метаданные в таблицу, которую среда выполнения C ++ будет использовать для определения порядка разрешения методов.

Python работает совсем по-другому; сам класс не определяет расположение атрибутов; скорее, когда пришло время создать экземпляр класса, среда выполнения берет union всех __slots__, определенных в каждом родительском классе для этого конкретного экземпляра.

В C ++ то, как вы определяете классы, определяет, как эти классы собираются, но в python они просто как-то перемешаны (но все еще четко определены), так что вы не можете точно сказать, где один. класс заканчивается, а следующий начинается на уровне отдельного экземпляра, и это на самом деле является лишь следствием того, что объекты Python являются просто «пакетами атрибутов»

1 голос
/ 15 июля 2011

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!']
...