在 Python 中处理可变默认参数的方法是将它们设置为 None。
例如:
def foo(bar=None):
bar = [] if bar is None else bar
return sorted(bar)
Run Code Online (Sandbox Code Playgroud)
如果我输入函数定义,那么唯一的类型 forbar说的bar是Optional,很明显,它不是Optional我期望sorted在其上运行该函数的时间:
def foo(bar: Optional[List[int]]=None):
bar = [] if bar is None else bar
return sorted(bar) # bar cannot be `None` here
Run Code Online (Sandbox Code Playgroud)
那么我应该投吗?
def foo(bar: Optional[List[int]]=None):
bar = [] if bar is None else bar
bar = cast(List[int], bar) # make it explicit that `bar` cannot be `None`
return sorted(bar) …Run Code Online (Sandbox Code Playgroud) 以下代码mypy按预期被拒绝:
def foo(value: int) -> None:
print(value, type(value))
foo(None)
Run Code Online (Sandbox Code Playgroud)
输出:
error: Argument 1 to "foo" has incompatible type "None"; expected "int"
Run Code Online (Sandbox Code Playgroud)
但是在引入了一个默认参数之后None,就没有错误了:
def foo(value: int=None) -> None:
print(value, type(value))
foo(None)
Run Code Online (Sandbox Code Playgroud)
如果我们从to更改,我希望mypy只允许None(作为参数和默认值),但似乎不需要这样做。为什么?valueintOptional[int]
这不是一个大问题,但作为一种风格问题,我想知道指示可选函数参数的最佳方法......
在类型提示之前,参数是这样的b:
def my_func(a, b = None)
Run Code Online (Sandbox Code Playgroud)
在 Python 3.10 之前,使用类型提示:
def my_func(a, b: Optional[str])
Run Code Online (Sandbox Code Playgroud)
使用 Python 3.10 可爱的管道类型表示法(参见PEP 604):
def my_func(a, b: str | None)
Run Code Online (Sandbox Code Playgroud)
后者似乎是三个选项中显而易见的选择,但我想知道这是否完全消除了指定默认 值的需要None,默认值是:
def my_func(a, b: str | None = None)
Run Code Online (Sandbox Code Playgroud)
编辑:感谢@deceze和@jonrsharpe指出,def my_func(a, b: str | None)仍然需要您将值传递给b:如果您想要的话,您将明确必须传递None。
因此,确保其b可选(即调用者根本不必传递值)的最简洁的方法是:
def my_func(a, b: str = None)
Run Code Online (Sandbox Code Playgroud)
从风格上来说,合并显式类型(def my_func(a, b: str | None = None)即显式可选类型加上默认None …
比较这两个函数:
from typing import Optional
def foo1(bar: str = None) -> None:
print(bar)
def foo2(bar: Optional[str] = None) -> None:
print(bar)
Run Code Online (Sandbox Code Playgroud)
Mypy 不会抱怨他们中的任何一个。那么Optional[]真的有必要吗?这两个声明之间有什么细微的区别吗?
python ×4
mypy ×2
mutable ×1
nonetype ×1
python-3.10 ×1
python-3.x ×1
type-hinting ×1
typechecking ×1
typing ×1