【问题标题】:Default vs optional function parameters with type hints带有类型提示的默认与可选函数参数
【发布时间】:2020-02-18 13:33:37
【问题描述】:

所以函数gendata 接受两个可选参数(namesource),然后根据source 的值调用parser,但参数与此函数中所需的参数相同。

  1. 解决必需参数与无必需参数的推荐方法是什么?
  2. Python 文档中有一个typing.Types 的示例,它表明Type[SuperClass] 应该接受所有继承自它的子类。为什么mypy 在这种情况下会抱怨,为什么只针对 arg 1 和 2 而不是 3 (source)?

exmaple.py:

from dataclasses import dataclass
from typing import List, Optional, Type


@dataclass
class BaseItem:
    name: str
    value: int


@dataclass
class Item(BaseItem):
    pass


@dataclass
class AnotherItem(BaseItem):
    pass


def parser(item: Type[BaseItem], name: str, source: int) -> Type[BaseItem]:
    item.value = source
    return item


def gendata(
    items: List[Item], name: Optional[str] = None, source: Optional[int] = None
) -> None:
    for item in items:
        if source:
            item = parser(item, name, source)

测试:

$ mypy example.py 
e.py:31: error: Incompatible types in assignment (expression has type "Type[BaseItem]", variable has type "Item")
e.py:31: error: Argument 1 to "parser" has incompatible type "Item"; expected "Type[BaseItem]"
e.py:31: error: Argument 2 to "parser" has incompatible type "Optional[str]"; expected "str"
Found 3 errors in 1 file (checked 1 source file)

【问题讨论】:

    标签: python type-hinting type-annotation


    【解决方案1】:

    首先,关于Type[Something] 错误,根据文档,当您收到类型作为参数时,您应该使用Type[Something],如果您收到BaseItem 的实例,您应该只使用BaseItem.

    例子:

    a = 3         # Has type 'int'
    b = int       # Has type 'Type[int]'
    c = type(a)   # Also has type 'Type[int]'
    

    参考:https://docs.python.org/3/library/typing.html#typing.Type


    关于Optional 错误,我通常将可选读作nullable(在文档中他们甚至说Optional[X] 等同于Union[X, None]

    参考:https://docs.python.org/3/library/typing.html#typing.Optional

    因此,如果您收到Optional[str] 类型的参数并尝试传递给接收str 的函数,这将引发错误,一种解决方案是检查值是否为None 并输入改为默认字符串,例如:

    def gendata(
        items: List[Item], name: Optional[str] = None, source: Optional[int] = None
    ) -> None:
        if name is None:
            name = ''
        if source:
            for item in items:
                item = parser(item, name, source)
    

    【讨论】:

    • 进一步说明:mypy 可以从name: str = None 中的默认值None 推断出Optional[str]
    猜你喜欢
    • 2012-01-21
    • 2011-11-06
    • 1970-01-01
    • 2018-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-08
    相关资源
    最近更新 更多