Тип аннотации с несколькими типами в **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)