Ближайшая вещь к виртуальному вызову в Python - PullRequest
1 голос
/ 23 сентября 2019

Python не предоставляет некоторый встроенный механизм наследования для вызова реализаций базовых виртуальных или абстрактных методов в производном классе из базовых методов

Мне интересно, что является самым близким в Python средством, которое обеспечивало быследующая структура:

class Base(?):
   def some_abstract_interface(self, **params):
     raise Unimplemented()
   def some_base_impl(self):
     self.some_abstract_interface(self, a=4, b=3, c=2)


class Derived(Base):

   @neat_override_decorator_here? 
   def some_abstract_interface(self, **params):
     print("actual logic here {0}".format(params))

d = Derived()
d.some_base_impl()
>>>output: actual logic here a=4, b=3, c=2

Ответы [ 2 ]

6 голосов
/ 23 сентября 2019

Вы уже можете сделать это без какого-либо аккуратного декоратора:

class Base:
    def some_abstract_interface(self):
        raise NotImplemented

    def some_base_impl(self):
        self.some_abstract_interface()

class Derived(Base):
    def some_abstract_interface(self):
        print('actual logic here')

Derived().some_base_impl()

Это выводит:

actual logic here

Если вы хотите, чтобы Base был абстрактным классом и не может бытьиспользуется для непосредственного создания экземпляра объекта, и что some_abstract_interface предназначен для абстрактного метода и всегда должен быть переопределен реализацией метода из дочернего класса, базовый класс можно наследовать от класса ABCмодуль abc и декорируйте абстрактные методы с помощью abc.abstractmethod следующим образом:

import abc

class Base(abc.ABC):
    @abc.abstractmethod
    def some_abstract_interface(self):
        raise NotImplemented

    def some_base_impl(self):
        self.some_abstract_interface()

class Derived(Base):
    def some_abstract_interface(self):
        print('actual logic here')

Derived().some_base_impl()
4 голосов
/ 23 сентября 2019

Вы просто делаете звонок сами.Это не будет тяжелее, синтаксически, чем декоратор, который вы устанавливаете.

class Derived(Base):
    def some_abstract_interface(self, **params):
        self.some_base_impl()
        print('actual logic her {0}.format(params))

На самом деле вам даже не нужно разделять some_base_impl и some_abstract_interace;абстрактный метод может иметь реализацию, но все же требует переопределения.

from abc import ABC, abstractmethod


class Base(ABC):
    @abstractmethod
    def some_abstract_interface(self, **params):
        pass  # Put base implementation here


class Derived(Base):
    def some_abstract_interface(self, **params):
        super().some_abstract_interface(**params)
        print("actual logic here {0}".format(params))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...