python - 覆盖python中的抽象方法
问题描述
覆盖python抽象方法时,有没有办法在方法签名中使用额外的参数覆盖该方法?
例如
抽象类 =
Agent(ABC):
@abstractmethod
def perceive_world(self, observation):
pass
继承类:
Dumb_agent(Agent):
def perceive_world(self, observation):
print('I see %s' % observation)
在方法签名中使用额外参数继承类:
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)
解决方案
你正在尝试做的事情只会奏效——但这是一个非常糟糕的主意。
通常,您不希望在覆盖时以不兼容的方式更改方法的签名。这是里氏替换原则的一部分。
在 Python 中,通常有充分的理由违反这一点——继承并不总是与子类型有关。
但是,当您使用 ABC 定义接口时,这显然是关于子类型化的。ABC
这是子类和装饰器的唯一目的abstractmethod
,所以用它们来表示其他任何东西充其量是高度误导的。
更详细地说:
通过从 继承Agent
,您声明任何 的实例都Clever_Agent
可以像使用Agent
. 这包括能够打电话my_clever_agent.perceive_world(my_observation)
。事实上,它不仅包括这些。这就是它的全部含义!如果那个调用总是失败,那么 noClever_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)
推荐阅读
- java - 不稳定的 Google Cloud Engine - 标准环境 - 延迟(Spring Boot 应用程序)
- java - 使用反射实例化匿名 Java 类
- f# - 在 F# 中使用没有类型的 Result<>
- javascript - 从公共网站将本地文件加载到 javascript 变量中
- google-sheets - Google表格:计算一列中与另一列中对应行不匹配的行数?
- c# - 如何避免 CompleteAsync(如何多次接收消息)?
- android - 即使不满足限制条件,定期工作请求仍在运行
- unix - Unix如何使用特定用户创建文件和目录
- java - Java 项目在 Eclipse 上运行,但在使用批处理时出错
- python - 静态 CSS 未应用于 django-allauth 模板