Mypy允许我们编写可以与实际类放在同一目录中的类存根。该存根与其他语言中的接口非常相似。客户端可以使用存根,并且实现严格遵循存根吗?
示例我想工作:
class IDependency:
def do_something(self) -> None: ...
def do_something_else(self) -> None: ...
class Service:
def __init__(self, dependency: IDependency):
dependency.do_something()
dependency.do_something_else() # this fails silently
class DependencyImplementation(IDependency):
def do_something(self) -> None:
print("doing something")
# Note there is no `do_something_else` here.
这有效。但是,如果DependencyImplementation
未实现该do_something
方法,则Mypy不会出错,Python本身也不会出错。该呼叫只是不执行任何操作。我是否必须编写raise NotImplementedException()
或注释每种方法@abc.abstractmethod
才能起作用?Mypy或Python解释器中是否有一些特殊标志?
这是Mypy协议的用例吗?它似乎即将到来(也许是Python 4?)
实际上,您可以使用@abc.abstractmethod
或协议来执行此操作。前者类似于使用Java的抽象类。后者将类似于使用Go的界面或Rust特征。
这是使用ABC的示例:
from abc import abstractmethod
class Parent:
@abstractmethod
def foo(self) -> None: ...
# Missing an implementation for 'foo'!
class Child(Parent): pass
print(Child()) # Error: Cannot instantiate abstract class 'Child' with abstract attribute 'foo'
有关此示例的一些注意事项:
foo
在第二个子类中进行定义的用例。abc
元类添加到Parent(例如class Parent(metaclass=ABCMeta)
):mypy将了解@abc.abstractmethod
使用或不使用它的含义。仅当您希望Python解释器也强制您正确覆盖了在运行时标记为抽象的所有内容时,才包括元类。您也可以使用协议,尽管现在您需要先pip install typing_extensions
使用它。这是一个例子:
from typing_extensions import Protocol
class CanFoo(Protocol):
def foo(self) -> None: ...
class Child: pass
def expects_fooable(x: CanFoo) -> None: ...
x = Child()
expects_fooable(x) # Error: Argument 1 to "expects_fooable" has incompatible type "Child"; expected "CanFoo"
一些注意事项:
Child
不是故意继承的CanFoo
:类与它所实现的协议之间没有明确的链接:协议与Go风格的接口非常相似,并且可以是临时的。将此与Java之类的语言进行对比,您确实需要在类定义中包括“ implements Blah”。Child
:它没有内在的错误。相反,当我们尝试不正确使用它时,我们会得到一个例外。最后几点注意事项:
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句