为什么Python中没有@override装饰器来帮助编写代码可读性?

gny*_*his 18 python inheritance python-decorators

我一直在使用Python中的抽象类ABCMeta.当你编写一个抽象方法时,你用装饰器标记它@abstractmethod.我发现奇怪的一件事(和其他语言不同)是当子类重写超类方法时,没有@override提供类似的装饰器.有谁知道这背后的逻辑是什么?

这使得读取代码的人快速确定哪些方法覆盖/实现抽象方法与仅存在于子类中的方法有点混淆.

use*_*ica 10

尝试添加的问题@override是在方法定义时,装饰器无法判断该方法是否实际覆盖了另一个方法.它无权访问父类(或当前类,甚至还不存在!).

如果要添加@override,@override装饰器实际上不能执行任何覆盖检查.然后你有两个选择.无论是有无覆盖检查,在此情况下,@override没有比一个更好的意见或type构造函数需要具体了解@override,并在类的创建时间检查.像这样的便利功能@override不应该像这样复杂类型系统实现的核心部分.此外,如果您不小心@override使用了非方法,则在您尝试调用修饰函数并获得奇怪的TypeError之前,该错误将不会被检测到.

  • @NeilG:嗯,这是 `abstractmethod` 工作原理的一部分,因为他们还 [将一些检查烘焙到 `object.__new__`](https://github.com/python/cpython/blob/3.6/Objects/typeobject. c#L3503)。我总是觉得设计需要一个特定的元类并且 * 仍然 * 将一些实现放在像`object.__new__`这样的核心位置有点奇怪。看起来如果他们打算把东西放在 `object.__new__` 中,他们不妨将 `ABCMeta` 的功能直接折叠到 `type` 中。 (2认同)

Dan*_*man 8

你将Python装饰器与Java注释混淆了.尽管语法相似,但它们完全不同.Java注释是对编译器的指令.但是Python装饰器是可执行代码,可以执行具体的操作:它将函数包装在另一个可以改变其功能的函数中.这与abstractmethod的情况一样,与任何其他装饰器一样多; 它做了一些事情,即告诉ABC有一种方法需要覆盖.

  • @ShadowRanger` @ Override`不仅仅用于文档目的(为此,你*可以*添加代码注释...).如果带注释的方法不是*真的*覆盖基类中的方法,它将无法编译.这是一项安全检查.添加"id函数"作为装饰器不会提供这样的安全检查. (3认同)
  • 这与 Java 无关 - 至少您也可以在 C++ 和 C# 中执行此操作。认为您正在覆盖父类上的方法,而实际上由于拼写错误或参数不匹配(这在 Python 中不会发生)而实际上并没有这样做,这是任何有经验的程序员都犯过的严重且无声的错误不止一次。`@overrides` 注释应该尽早导致失败,以防止您默默地犯这样的错误。 (3认同)
  • 请注意,如果您真的想要为自己的(可疑的)可读性优势添加注释,那么这样做既简单又便宜。`def override(func): return func`。完毕。注释可用。有效地免费应用它(在导入时,您支付调用 noop 装饰器函数的微不足道的成本),玩得开心。 (2认同)