在** kwargs中键入多个类型的注释

时间:2017-06-02 13:48:44

标签: python python-3.x type-hinting typing 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可能包含多种类型的参数 - floatboolstr

现在,我正在尝试为函数编写类型注释,如下所示:

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

但我的PyCharm IDE警告我:

  

除了'Integral'类型,改为'str'而不是

  

在bool中找不到referance'get' str |浮动“

我做错了吗?

如果kwargs包含来自多个类型的参数,我该如何编写kwargs的类型注释?

2 个答案:

答案 0 :(得分:2)

请参阅PyCharm问题跟踪器上的this bugthis bug。这显然是PyCharm检查器的一个问题; mypy(Python的另一种类型检查器)在执行类似代码时不会抱怨

已经解决了这个问题,显然可以使用in build 171.2014.23。在那之前,我认为Any 足以作为一种临时解决方法,让检查员停止抱怨。

答案 1 :(得分:0)

如果想要描述 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)