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 错误,我总是使用注释掉的两个习惯用法之一。
还有其他解决方案吗?
为什么不使用类的实例Default而不是类本身呢?MyPy理解 isinstance并可以推断其中使用的对象类型,这与使用的类型缩小相反is.
至于使用类的实例作为参数的默认值:根据函数定义部分,没有显着的开销,可以忽略不计:
\n\n\n执行函数定义时,默认参数值从左到右计算。这意味着在定义函数时,表达式会计算一次,并且每次调用都会使用相同的 \xe2\x80\x9cpre-compulated\xe2\x80\x9d 值。
\n
例如:
\nfrom 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).\')\nRun Code Online (Sandbox Code Playgroud)\n