提问人:Sean 提问时间:2/6/2023 更新时间:2/6/2023 访问量:98
Python3 中的鸭子类型注解
Duck Typing Annotations in Python3
问:
我正在尝试将类型注释添加到函数输入参数中,该参数的属性与另一个属性重叠,实际上作为输入参数传入。dataclass
dataclass
请考虑以下代码:
from dataclasses import dataclass
from typing import TypeVar
@dataclass
class Foo:
a: str
zar: str
@dataclass
class Car(Foo):
b: str
@dataclass
class CarInterface:
a: str
b: str
mar = TypeVar("mar", bound=CarInterface)
def blah(x: mar):
print(x.a)
car_instance = Car(a="blah blah", zar="11", b="bb")
blah(car_instance)
在此示例中,我尝试创建自己的类型注释,该注释受 .我想检查传递给的任何类是否至少具有 和属性(不在乎该类是否具有其他属性,例如)。我想这样做,因为类(实际上被传入)是将来将要编写并传递到此函数中的众多类之一。mar
CarInterface
blah()
a
b
zar
Car
我还希望定义一个新的非常容易,所以我想避免抽象类,因为我认为增加的复杂性不值得我高兴。Car
所以我正在尝试创建使用 duck 类型来表示满足 的接口。mar
Car
CarInterface
但是,我收到两个mypy错误。
第一个是关于注解mar
def blah
TypeVar "mar" appears only once in generic function signaturePylancereportInvalidTypeVarUse
另一个是我进入的地方car_instance
blah()
Argument of type "Car" cannot be assigned to parameter "x" of type "bar@blah" in function "blah"
Type "Car" cannot be assigned to type "CarInterface"
"Car" is incompatible with "CarInterface"PylancereportGeneralTypeIssues
答:
4赞
Samwise
2/6/2023
#1
使用 a 来定义,而不是 :Protocol
CarInterface
dataclass
from dataclasses import dataclass
from typing import Protocol
@dataclass
class Foo:
a: str
zar: str
@dataclass
class Car(Foo):
b: str
class CarInterface(Protocol):
a: str
b: str
def blah(x: CarInterface):
print(x.a)
car_instance = Car(a="blah blah", zar="11", b="bb")
blah(car_instance)
上面的代码可以正常类型检查,但是如果您尝试传递 a 而不是 a,则会出现如下 mypy 错误:blah
Foo
Car
test.py:22: error: Argument 1 to "blah" has incompatible type "Foo"; expected "CarInterface"
test.py:22: note: "Foo" is missing following "CarInterface" protocol member:
test.py:22: note: b
Found 1 error in 1 file (checked 1 source file)
A 可以用作 a 的边界,但只有当您想指示两个变量不仅实现协议而且是相同的特定类型时才需要使用 a(例如,指示函数接受任何对象实现并返回相同类型的对象而不是其他任意实现)。Protocol
TypeVar
TypeVar
CarInterface
CarInterface
评论