【发布时间】:2021-07-24 14:05:36
【问题描述】:
考虑以下代码:
from typing import Protocol
class IDE(Protocol):
def execute(self) -> None:
...
class Pycharm:
def execute(self) -> None:
print("Running pycharm")
class VsCode:
def execute(self) -> None:
print("Running VSCode")
class StringParser:
def execute(self) -> None:
print("Parsing string...")
print("Done!")
class Foo:
def bar(self) -> None:
print("Hello")
class Code:
def execute(self, ide: IDE) -> None:
ide.execute()
def main() -> None:
foo = Foo()
sp = StringParser()
vscode = VsCode()
pycharm = Pycharm()
code = Code()
code.execute(pycharm)
code.execute(vscode)
code.execute(sp)
# code.execute(foo)
if __name__ == "__main__":
main()
这比使用名为IDE 的抽象基类然后在VsCode 和Pycharm 中子类化它是否更具Python 风格?
据我了解,使用Protocol 的优点主要在于进行静态类型检查,而缺点主要是代码中的使用意图更加模糊。
另一方面,使用 ABC 方法确实可以明确告诉您哪个类应该工作,哪个不工作。此外,它还可以作为一个很好的文档。我不确定这有什么缺点,除了可能更冗长。我可以通过基类的类型提示来进行类型检查。在这两种情况下,StringParser 都会因为鸭子打字而起作用,在这种情况下,这有点不幸。
那么哪个更可取,也被认为更pythonic?
【问题讨论】:
-
你对pythonic的定义是什么?
-
我不认为这是其中之一。继承提供名义子类型,而
Protocol支持结构子类型。 ABC 不仅允许 重写继承的方法,而且要求 它,从而增加了名义子类型化。它以相当弱的形式这样做,因为关闭覆盖检查很容易。
标签: python python-3.x interface abstract-class