与 Union 元素不兼容的类型

zat*_*heo 1 python type-hinting mypy python-typing python-3.9

我最近收到了这个很好的答案,用于以下方面:

from typing import Union, cast


class Default:
    """Placeholder for default arguments."""


# ham[] is mutable.  `None` has meaning (or is not preferred).
def spam(ham: Union[list[str], None, type[Default]] = Default):
    if ham is Default:
        ham = ['prosciutto', 'jamon']
    #ham = cast(Union[list[str], None], ham)
    #assert isinstance(ham, (list, type(None)))
    if ham is None:
        print('Eggs?')
    else:
        print(str(len(ham)) + ' ham(s).')
Run Code Online (Sandbox Code Playgroud)

mypy错误:

Failed (exit code: 1) (2655 ms)

main.py:17: error: Argument 1 to "len" has incompatible type "Union[List[str], Type[Default]]"; expected "Sized"
Found 1 error in 1 file (checked 1 source file)
Run Code Online (Sandbox Code Playgroud)

为了避免类似的 mypy 错误,我总是使用注释掉的两个习惯用法之一。

还有其他解决方案吗?

ale*_*ame 5

为什么不使用类的实例Default而不是类本身呢?MyPy理解 isinstance并可以推断其中使用的对象类型,这与使用的类型缩小相反is.

\n

至于使用类的实例作为参数的默认值:根据函数定义部分,没有显着的开销,可以忽略不计:

\n
\n

执行函数定义时,默认参数值从左到右计算。这意味着在定义函数时,表达式会计算一次,并且每次调用都会使用相同的 \xe2\x80\x9cpre-compulated\xe2\x80\x9d 值。

\n
\n
\n

例如:

\n
from typing import Union, cast\n\n\nclass Default:\n    """Placeholder for default arguments."""\n\n\n# ham[] is mutable.  `None` has meaning (or is not preferred).\ndef spam(ham: Union[list[str], None, Default] = Default()):\n    if isinstance(ham, Default):\n        ham = [\'prosciutto\', \'jamon\']\n    if ham is None:\n        print(\'Eggs?\')\n    else:\n        print(str(len(ham)) + \' ham(s).\')\n
Run Code Online (Sandbox Code Playgroud)\n