Укажите ключи для mypy в словаре Python - PullRequest
0 голосов
/ 02 февраля 2019

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

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

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

Мой вопрос:

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

Ответы [ 2 ]

0 голосов
/ 30 марта 2019

Также столкнулся с этой проблемой, пытаясь ввести несколько типов в интеграцию 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 production .

0 голосов
/ 02 февраля 2019

Есть несколько способов и предположить, что ваша структура данных должна иметь только те же атрибуты, но они не используют dicts.

Вместо передачи 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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...