Укажите ключи для mypy в словаре Python
Предположим, у меня есть такой код
def get_x(d: dict) -> int:
d["x"]
Тем не менее, я хочу сказать, что Mypy d
должен содержать только определенные ключи (например, только ключ "x"). Таким образом, если я сделаю ошибку ниже в коде, пытаясь сослаться на неверный ключ d
Mypy вызовет ошибку.
Мой вопрос:
- Это возможно? Может ли mypy проверять ключи словаря?
- Если да, то как это сделать? Если нет, есть ли предпочтительный обходной путь?
1 ответ
Также столкнулся с этой проблемой, когда попытался немного поработать над интеграцией AWS API Gateway/Lambda.
Как отметил @Michael0x2a в комментариях, TypedDict может показаться вам подходящим, особенно потому, что он не требует каких-либо преобразований самостоятельно перед передачей в функцию (требование к ответам API, как вы упомянули).
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
производственная зависимость.
Есть несколько способов и предположить, что ваша структура данных должна иметь только те же атрибуты, но они не используют диктовку.
Вместо прохождения в dict
Вы можете использовать именованный кортеж. Используя namedtuple, вы можете рассматривать его как объект, но новые поля также не могут быть добавлены.
from collections import namedtuple
A = namedtuple("A", ["x", "y", "z"])
def get_x(d: A) -> int:
d.x
Другой способ - создать класс и использовать __slot__
приписывать. Это также позволяет избежать случайного добавления новых атрибутов.
class A:
__slot__ = ["x", "y", "z"]
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
Используя вышеуказанные методы, вы должны определить поля в самом начале.