混合类型映射的更强类型注释
Stronger type-annotation for a mixed-type mapping
假设我有一个映射,它在一个字典中映射字符串 -> int 和 int -> 字符串。有没有办法以严格的方式用类型注释来表达它?目前我可以做到 Dict[Union[str, int], Union[str, int]]
,但这允许 str -> str 和 int -> int,我实际上并不想要。
有人可能会尝试 Union[Dict[str, int], Dict[str, int]]
,但其中只有一个适用于它出现的范围。
这可能是一个解决方案。如果需要,您可以重新定义其他方法。
您还可以执行 d=cast(mydict,existing_dict)
.
from typing import overload
class mydict(dict):
@overload
def __getitem__(self, k: int) -> str: ...
@overload
def __getitem__(self, k: str) -> int: ...
def __getitem__(self, k):
return super(mydict, self).__getitem__(k)
@overload
def __setitem__(self, k: int, v: str) -> None: ...
@overload
def __setitem__(self, k: str, v: int) -> None: ...
def __setitem__(self, k, v):
super(mydict, self).__setitem__(k, v)
m = mydict()
m['a'] = 1
m[1] = 'a'
x1: str = m[1]
x2: int = m['a']
m['a'] = 1
m[1] = 'a'
x3: int = m[1] # mypy error
x4: str = m['a'] # mypy error
m[2] = 2 # mypy error
m['b'] = 'b' # mypy error
@MisterMiyagi 如何建议,协议也可以工作:
from typing import overload, Protocol
class mydictprotocol(Protocol):
@overload
def __getitem__(self, k: int) -> str: ...
@overload
def __getitem__(self, k: str) -> int: ...
@overload
def __setitem__(self, k: int, v: str) -> None: ...
@overload
def __setitem__(self, k: str, v: int) -> None: ...
假设我有一个映射,它在一个字典中映射字符串 -> int 和 int -> 字符串。有没有办法以严格的方式用类型注释来表达它?目前我可以做到 Dict[Union[str, int], Union[str, int]]
,但这允许 str -> str 和 int -> int,我实际上并不想要。
有人可能会尝试 Union[Dict[str, int], Dict[str, int]]
,但其中只有一个适用于它出现的范围。
这可能是一个解决方案。如果需要,您可以重新定义其他方法。
您还可以执行 d=cast(mydict,existing_dict)
.
from typing import overload
class mydict(dict):
@overload
def __getitem__(self, k: int) -> str: ...
@overload
def __getitem__(self, k: str) -> int: ...
def __getitem__(self, k):
return super(mydict, self).__getitem__(k)
@overload
def __setitem__(self, k: int, v: str) -> None: ...
@overload
def __setitem__(self, k: str, v: int) -> None: ...
def __setitem__(self, k, v):
super(mydict, self).__setitem__(k, v)
m = mydict()
m['a'] = 1
m[1] = 'a'
x1: str = m[1]
x2: int = m['a']
m['a'] = 1
m[1] = 'a'
x3: int = m[1] # mypy error
x4: str = m['a'] # mypy error
m[2] = 2 # mypy error
m['b'] = 'b' # mypy error
@MisterMiyagi 如何建议,协议也可以工作:
from typing import overload, Protocol
class mydictprotocol(Protocol):
@overload
def __getitem__(self, k: int) -> str: ...
@overload
def __getitem__(self, k: str) -> int: ...
@overload
def __setitem__(self, k: int, v: str) -> None: ...
@overload
def __setitem__(self, k: str, v: int) -> None: ...