l0b*_*0b0 1 python mypy python-typing
Mypy 认为这对以下情况有效strict = true:
from typing import Dict, TypeVar
KeyType = TypeVar("KeyType")
ValueType = TypeVar("ValueType")
class InvertibleDict(Dict[KeyType, ValueType]):
def __inverse__(self) -> "InvertibleDict[ValueType, KeyType]":
new_instance: "InvertibleDict[ValueType, KeyType]" = self.__class__()
for key, value in self.items():
new_instance[value] = key
return new_instance
Run Code Online (Sandbox Code Playgroud)
但是,它不接受相同代码的以下更简洁版本,在最后一行说“关键字必须是字符串”:
from typing import Dict, TypeVar
KeyType = TypeVar("KeyType")
ValueType = TypeVar("ValueType")
class InvertibleDict(Dict[KeyType, ValueType]):
def __inverse__(self) -> "InvertibleDict[ValueType, KeyType]":
return self.__class__(**{value: key for key, value in self.items()})
Run Code Online (Sandbox Code Playgroud)
MyPy 在这里是正确的,它在您的实现中捕获了一个错误(静态类型检查的美妙之处)。类型:
{value: key for key, value in self.items()}
Run Code Online (Sandbox Code Playgroud)
是Dict[KeyType, ValueType],但是当您这样做时,通常会失败:
dict(**some_mapping)
Run Code Online (Sandbox Code Playgroud)
不保证键是字符串的地方。
观察:
>>> dict(**{1:2,3:4})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: keywords must be strings
Run Code Online (Sandbox Code Playgroud)
你只想要:
return self.__class__({value: key for key, value in self.items()})
Run Code Online (Sandbox Code Playgroud)
一般不会失败:
>>> dict({1:2,3:4})
{1: 2, 3: 4}
Run Code Online (Sandbox Code Playgroud)
就个人而言,我会采用您的第一个实现,而不会不必要地浪费 2 倍所需的空间,并进行不必要的第二遍。
请注意,您可能永远不会使用**解包来初始化 dict,构造函数的关键字参数形式对于编写以下内容很方便:
>>> dict(foo=1, bar=2)
{'foo': 1, 'bar': 2}
Run Code Online (Sandbox Code Playgroud)
您甚至可以在复制字典但想要为特定字符串键强制一个值时使用这个方便的技巧:
>>> dict({'foo': 1, 'bar': 2}, bar=42)
{'foo': 1, 'bar': 42}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
36 次 |
| 最近记录: |