Тип аннотации с несколькими типами в **kwargs

Я пытаюсь использовать Python type annotations с абстрактным классом. мой __init__ функция выглядит так:

from abc import ABCMeta

class SomeClass(object, metaclass=ABCMeta):
    def __init__(self, *args, **kwargs):
        print("Initiating %s object.", self.__class__.__name__)

        self.username = kwargs['data']
        assert isinstance(self.username, str)

        is_premioum = kwargs.get('premioum', False)

        self.money_investmant = kwargs.get('investmant')
        if isinstance(self.money_investmant, str):
            self.money_investmant = float(self.money_investmant)

Как вы видете, kwargs может содержать аргументы из нескольких типов float, bool а также str,

Теперь я пытаюсь написать аннотацию типа для функции, которая выглядит следующим образом:

def __init__(self, *args, **kwargs: Union[bool, str, float]) -> None:

Но мой PyCharm IDE предупреждает меня:

За исключением типа "Интеграл", вместо него получен "str"

А также:

Не удается найти ссылку 'get' в bool | ул | поплавок"

Я делаю что-то неправильно?

Как мне написать аннотацию типа для kwargs, если она содержит аргументы нескольких типов?

2 ответа

Решение

Смотрите эту ошибку и эту ошибку на трекере ошибок для PyCharm. По-видимому, это проблема проверки PyCharm; mypy (другой тип проверки для Python) не жалуется, когда я выполняю аналогичный код.

Это уже исправлено и, по-видимому, доступно в сборке 171.2014.23. До тех пор, я бы предположил Any было бы достаточно в качестве временного обходного пути, чтобы заставить контролера прекратить жаловаться.

Если кто-то хочет описать конкретные именованные аргументы, ожидаемые в kwargs, вместо этого можно передать TypedDict, который определяет обязательные и необязательные параметры. Необязательные параметры - это какие были kwargs:

Это позволяет иметь неустановленные (НЕ по умолчанию) необязательные аргументы И иметь подсказки типа для них.

      import typing
from abc import ABCMeta


class RequiredProps(typing.TypedDict):
    # all of these must be present
    data: str

class OptionalProps(typing.TypedDict, total=False):
    # these can be included or they can be omitted
    premium: bool
    investment: typing.Union[str, float]

class ReqAndOptional(RequiredProps, OptionalProps):
    pass

class SomeClass(object, metaclass=ABCMeta):
    def __init__(self, *args, kwargs: ReqAndOptional):
        print("Initiating %s object.", self.__class__.__name__)

        self.username = kwargs['data']
        assert isinstance(self.username, str)

        is_premium = kwargs.get('premium', False)
        assert isinstance(is_premium, bool)

        self.money_investment = kwargs.get('investment')
        assert isinstance(elf.money_investment, (str, float))
        if isinstance(self.money_investment, str):
            self.money_investment = float(self.money_investment)
Другие вопросы по тегам