在 python 字典中为 mypy 指定键
Specify keys for mypy in python dictionary
假设我有这样的代码
def get_x(d: dict) -> int:
d["x"]
但是,我想告诉 mypy d
应该只包含某些键(例如只包含 "x" 键)。这样,如果我在尝试引用 d
的无效键的代码中犯了错误,mypy 将触发错误。
我的问题是:
- 这可能吗? mypy 可以验证字典键吗?
- 如果是,这是怎么做到的?如果否,是否有首选解决方法?
有几种方法并假设您的数据结构必须只具有相同的属性,但它们不使用字典。
您可以使用 namedtuple,而不是传入 dict
。使用命名元组,你可以把它当作一个对象,但也不能添加新的字段。
from collections import namedtuple
A = namedtuple("A", ["x", "y", "z"])
def get_x(d: A) -> int:
d.x
另一种方法是创建 class 并使用 __slot__
属性。这也使得不会意外插入新属性。
class A:
__slot__ = ["x", "y", "z"]
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
使用上述方法,必须在最开始定义字段。
运行 在尝试围绕 AWS API Gateway/Lambda 集成时也遇到了这个问题。
正如@Michael0x2a 在评论中指出的那样,TypedDict 似乎是可行的方法,特别是因为它在传递给函数之前不需要自己进行任何转换([=23 的要求=] 回复,就像你提到的那样)。
from mypy_extensions import TypedDict
DictWithOnlyX = TypedDict('DictWithOnlyX', {"x": str})
# error: Extra key 'y' for TypedDict "DictWithOnlyX@58"
dx1: DictWithOnlyX = { "y": 123 }
# error: Incompatible types (expression has type "int",
# TypedDict item "x" has type "str")
dx2: DictWithOnlyX = { "x": 123 }
# GOOD!
dx3: DictWithOnlyX = { "x": "123" }
还应注意,如果在生产和 dev/test 之间分离依赖关系,那么这会使 mypy
成为 生产 依赖关系。
假设我有这样的代码
def get_x(d: dict) -> int:
d["x"]
但是,我想告诉 mypy d
应该只包含某些键(例如只包含 "x" 键)。这样,如果我在尝试引用 d
的无效键的代码中犯了错误,mypy 将触发错误。
我的问题是:
- 这可能吗? mypy 可以验证字典键吗?
- 如果是,这是怎么做到的?如果否,是否有首选解决方法?
有几种方法并假设您的数据结构必须只具有相同的属性,但它们不使用字典。
您可以使用 namedtuple,而不是传入 dict
。使用命名元组,你可以把它当作一个对象,但也不能添加新的字段。
from collections import namedtuple
A = namedtuple("A", ["x", "y", "z"])
def get_x(d: A) -> int:
d.x
另一种方法是创建 class 并使用 __slot__
属性。这也使得不会意外插入新属性。
class A:
__slot__ = ["x", "y", "z"]
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
使用上述方法,必须在最开始定义字段。
运行 在尝试围绕 AWS API Gateway/Lambda 集成时也遇到了这个问题。
正如@Michael0x2a 在评论中指出的那样,TypedDict 似乎是可行的方法,特别是因为它在传递给函数之前不需要自己进行任何转换([=23 的要求=] 回复,就像你提到的那样)。
from mypy_extensions import TypedDict
DictWithOnlyX = TypedDict('DictWithOnlyX', {"x": str})
# error: Extra key 'y' for TypedDict "DictWithOnlyX@58"
dx1: DictWithOnlyX = { "y": 123 }
# error: Incompatible types (expression has type "int",
# TypedDict item "x" has type "str")
dx2: DictWithOnlyX = { "x": 123 }
# GOOD!
dx3: DictWithOnlyX = { "x": "123" }
还应注意,如果在生产和 dev/test 之间分离依赖关系,那么这会使 mypy
成为 生产 依赖关系。