То, что вы пытаетесь сделать, просто сработает, но это очень плохая идея.
В общем, вы не хотите изменять сигнатуру метода несовместимыми способами при переопределении.Это часть принципа замены Лискова .
В Python часто есть веские причины нарушать это - наследование не всегда связано с подтипом.
Но когда вы 'Использование ABC для определения интерфейса, это явно подтип.Это единственная цель ABC
подклассов и abstractmethod
декораторов, поэтому использование их для обозначения чего-либо еще в лучшем случае вводит в заблуждение.
Более подробно:
Путем наследования отAgent
, вы заявляете, что любой экземпляр Clever_Agent
может использоваться, как если бы это был Agent
.Это включает в себя возможность звонить my_clever_agent.perceive_world(my_observation)
.На самом деле, это не просто включает это;это все, что это значит!Если этот вызов всегда будет неуспешным, то Clever_Agent
не будет Agent
, поэтому он не должен претендовать на это.
В некоторых языках вам иногда приходится подделывать свой способ проверки интерфейса, поэтому выПозже можно переключить тип и / или «динамическое приведение» обратно к фактическому типу.Но в Python это никогда не нужно.Нет такого понятия, как «список Agent
s», просто список чего-либо вообще.(Если вы не используете дополнительную проверку статического типа - но в этом случае, если вам нужно обойти проверку статического типа, не объявляйте статический тип только для того, чтобы обойти себя.)
В Python вы можете расширить метод за пределы его метода суперкласса, добавив необязательные параметры, и это совершенно правильно, поскольку он по-прежнему совместим с явно объявленным типом.Например, это было бы вполне разумно:
class Clever_Agent(Agent):
def perceive_world(self, observation, prediction=None):
print('I see %s' % observation)
if prediction is None:
print('I have no predictions about what will happen next')
else:
print('I think I am going to see %s happen next' % prediction)
Или даже это может быть разумно:
class Agent(ABC):
@abstractmethod
def perceive_world(self, observation, prediction):
pass
class Dumb_agent(Agent):
def perceive_world(self, observation, prediction=None):
print('I see %s' % observation)
if prediction is not None:
print('I am too dumb to make a prediction, but I tried anyway')
class Clever_Agent(Agent):
def perceive_world(self, observation, prediction):
print('I see %s' % observation)
print('I think I am going to see %s happen next' % prediction)