正在阅读定义协议 https://peps.python.org/pep-0544/#defining-a-protocol相关 pep (PEP 544) 的部分,示例实现(在他们的情况下,class Resource
)不直接继承自协议 - 他们的class SupportsClose
用作类型提示验证器的引用类型。
你的例子也让人想起长期以来的zope.interface
包,这个 PEP 也引用的 https://peps.python.org/pep-0544/#existing-approaches-to-structural-subtyping。请注意,PEP 的示例用法引用了以下示例(已删除无关行):
from zope.interface import Interface, implementer
class IEmployee(Interface):
...
@implementer(IEmployee)
class Employee:
...
The Employee
类确实not直接子类化自IEmployee
(对于新手 Zope/Plone 开发人员来说,这是一个常见的错误),它只是用zope.interface.implementer(IEmployee)
类装饰器来表示该类Employee
从接口实现IEmployee
.
同样,请进一步阅读本节下的内容礼宾成员 https://peps.python.org/pep-0544/#protocol-members,我们有一个模板和具体类的示例(再次,示例被修剪):
from typing import Protocol
class Template(Protocol):
name: str # This is a protocol member
value: int = 0 # This one too (with default)
class Concrete:
def __init__(self, name: str, value: int) -> None:
self.name = name
self.value = value
var: Template = Concrete('value', 42) # OK
再次请注意,Concrete
实施确实not继承自Template
,然而,变量var
被表示为具有预期类型Template
。请注意,Concrete
可以将实例分配给它,因为它与定义的预期协议相匹配Template
.
综上所述,鉴于您的示例,您可能希望定义class Foo:
按原样而不是继承自IFoo
正如您最初所做的那样,并填写类型信息,以便期望的事情IFoo
在相关上下文中适当地进行类型提示(例如some_foo: IFoo = Foo(...)
or def some_func(foo: IFoo):
).
作为附录,您可能希望定义Foo
像这样:
class Foo:
_value: int
@property
def value(self) -> int:
return 2
@value.setter
def value(self, value: int):
self._value = value
拥有_value
属性及其设置者之间的定义似乎令人困惑mypy
due to 这个问题 https://github.com/python/mypy/issues/1465.