Укажите ключи для mypy в словаре Python

Предположим, у меня есть такой код

def get_x(d: dict) -> int:
    d["x"]

Тем не менее, я хочу сказать, что Mypy d должен содержать только определенные ключи (например, только ключ "x"). Таким образом, если я сделаю ошибку ниже в коде, пытаясь сослаться на неверный ключ dMypy вызовет ошибку.

Мой вопрос:

  1. Это возможно? Может ли mypy проверять ключи словаря?
  2. Если да, то как это сделать? Если нет, есть ли предпочтительный обходной путь?

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

Используя вышеуказанные методы, вы должны определить поля в самом начале.

Другие вопросы по тегам