Наследование методов классов в pyton

Рейтинг: 1Ответов: 2Опубликовано: 29.03.2023

Метод класса наследника затирается методом предка.

При инициализации класса ExcelDataOwnerWithCaching вызывается метод __get_data класса DataOwner, а не DataOwnerWithCaching. Как мне добиться обратного, что я делаю не так?

from abc import ABC, abstractmethod


class DataOwner(ABC):
    def __init__(self, **kwargs):
        self.df = self.__get_data(
            self.load_data,
            **kwargs
        )

    @staticmethod
    @abstractmethod
    def load_data(**kwargs):
        pass

    def __get_data(self, data_loader, **kwargs):
        return data_loader(**kwargs)


class DataOwnerWithCaching(DataOwner, ABC):
    def __init__(self, key: str, **kwargs):
        self.key = key
        super().__init__(**kwargs)

    def __get_data(self, data_loader, **kwargs):
        """Тут проверка ключа в кэше и возврат данных либо из кэша, либо из главного источника + занесение в кэш"""
        print(data_loader, **kwargs)
        return pd.DataFrame()


class ExcelDataOwner(DataOwner):
    @staticmethod
    def load_data(path: str, **kwargs):
        return pd.DataFrame()


class ExcelDataOwnerWithCaching(DataOwnerWithCaching, ExcelDataOwner):
    pass


ExcelDataOwnerWithCaching(
    key='my_key',
    path='my_data.xlsx',
)

Ответы

▲ 2Принят

Добавив два подчеркивания вы превратили ваши методы в приватные, естественно они не могут быть переобъявлены в наследуемом классе. Достачно сделать их защищенными _get_data, чтобы все заработало

Дело в том, что python для приватных свойств и методов в словарь объекта добавляется не просто имя, а сочетание __<имя класса>_<имя> (в данном случае _DataOwner__get_data), поэтому они отсутствуют в словарях наследуемых классов

▲ 0

Чтобы вызвать метод __get_data() из DataOwnerWithCaching, необходимо явно указать его при вызове метода init() с помощью super():

class ExcelDataOwnerWithCaching(DataOwnerWithCaching, ExcelDataOwner):
    def __init__(self, key: str, **kwargs):
        super(DataOwnerWithCaching, self).__init__(key=key, **kwargs)