如何使用支持简单类型和 属性 的字段声明协议?
How to declare a Protocol with a field which supports both a simple type and property?
(相关但不重复:)
我想创建一个Protocol
,其中一个字段既可以用简单类型实现,也可以用属性实现。例如:
class P(Protocol):
v: int
@dataclass
class Foo(P):
v: int
class Bar(P):
@property
def v(self) -> int: # ERROR
return
但是上面的代码没有类型检查。我该如何解决?
注意:我想解决这个问题而不重写Foo
和Bar
,因为Foo
和Bar
不是我实现的
根据 this issue,以下代码不是解决方案,因为只读 property
和简单成员的语义略有不同。
class P(Protocol):
@property
def v(self) -> int: # declare as property
...
Pyright 否认 Protocol
由于差异。
一般来说,使用只读 property
声明 Protocol
,而不是 read/write 字段:
class P(Protocol):
@property
def v(self) -> int:
pass
这是必需的,因为 read-only property
和 read[=29= 都满足只读协议属性]/写字段。相比之下,read/write 协议属性仅由 read/write 字段满足,而不是 read-only property
.
由于 PyRight 坚持认为字段和属性是不同种类的属性,因此必须使用两种变体声明属性——一次作为字段,一次作为属性。对于简单的协议,这可以通过声明一个单独的字段和 属性 的 属性 变体来完成:
# field only
class Pf(Protocol):
v: int
# property only
class Pp(Protocol):
@property
def v(self) -> int:
return 1
# Either field or property
P = Union[Pf, Pp]
这对 MyPy 和 PyRight 都有效。
(相关但不重复:
我想创建一个Protocol
,其中一个字段既可以用简单类型实现,也可以用属性实现。例如:
class P(Protocol):
v: int
@dataclass
class Foo(P):
v: int
class Bar(P):
@property
def v(self) -> int: # ERROR
return
但是上面的代码没有类型检查。我该如何解决?
注意:我想解决这个问题而不重写Foo
和Bar
,因为Foo
和Bar
不是我实现的
根据 this issue,以下代码不是解决方案,因为只读 property
和简单成员的语义略有不同。
class P(Protocol):
@property
def v(self) -> int: # declare as property
...
Pyright 否认 Protocol
由于差异。
一般来说,使用只读 property
声明 Protocol
,而不是 read/write 字段:
class P(Protocol):
@property
def v(self) -> int:
pass
这是必需的,因为 read-only property
和 read[=29= 都满足只读协议属性]/写字段。相比之下,read/write 协议属性仅由 read/write 字段满足,而不是 read-only property
.
由于 PyRight 坚持认为字段和属性是不同种类的属性,因此必须使用两种变体声明属性——一次作为字段,一次作为属性。对于简单的协议,这可以通过声明一个单独的字段和 属性 的 属性 变体来完成:
# field only
class Pf(Protocol):
v: int
# property only
class Pp(Protocol):
@property
def v(self) -> int:
return 1
# Either field or property
P = Union[Pf, Pp]
这对 MyPy 和 PyRight 都有效。