提问人:Hyperplane 提问时间:9/1/2023 最后编辑:wjandreaHyperplane 更新时间:9/1/2023 访问量:78
如果可变的默认参数被注释为不可变,是否可以使用?
Is it OK to have a mutable default argument if it's annotated as immutable?
问:
通常,有充分的理由,在 python 中使用可变的默认参数被认为是不安全的。另一方面,总是必须把所有东西都包起来,并在功能开始时做小小的开箱舞,这是很烦人的。Optional
在想要允许传递给子函数的情况下,似乎还有另一种选择:**kwargs
def foo(
x: int,
subfunc_args: Sequence[Any] = (),
subfunc_kwargs: Mapping[str, Any] = {},
) -> R:
...
subfunc(*subfunc_args, **subfunc_kwargs)
显然,是一个可变的默认参数,因此被认为是不安全的。但是,由于被注释为 ,而不是 或 ,如果我们最终发生突变,类型检查器将引发错误。{}
subfunc_kwargs
Mapping
dict
MutableMapping
问题是:这是否被认为是可以做到的,还是仍然是一个可怕的想法?
不必跳小舞和有更整洁的签名,那就太好了。subfunc_kwargs = {} if subfunc_kwargs is None else subfunc_kwargs
注意:不是一个选项,因为这可能会与其他键发生冲突,如果更改 kwargs 会导致问题。**subfunc_kwargs
subfunc
答:
2赞
wjandrea
9/1/2023
#1
你不需要首先把自己放在这种情况中,因为你依赖于类型检查器,当你可以放置一个实际的不可变默认参数时:
from types import MappingProxyType
...
subfunc_kwargs: Mapping[str, Any] = MappingProxyType({})
请参阅什么是“冻结词典”?
评论
0赞
wjandrea
9/1/2023
我只是突然想到,这并不能完全解决标题中的问题,但我是设置新标题的人,我可能把它弄得太宽泛了。
0赞
Hyperplane
9/1/2023
谢谢,我不知道.PEP603 看起来也是一个非常好的解决方案。MappingProxyType
0赞
GabCaz
9/1/2023
#2
“不用跳小舞,签名更整洁,那就太好了。”subfunc_kwargs = {} if subfunc_kwargs is None else subfunc_kwargs
为什么会这样?在 Python 中,将默认值设置为是一个非常强大的选择,我认为健壮性和清晰度比优雅更可取(在它们发生冲突的情况下)。从某种意义上说,它也非常易于维护,所有开发人员都可以访问它,并且所有静态代码分析器都可以很好地理解它。None
评论
0赞
Hyperplane
9/1/2023
这真的很烦人和重复的样板😩.此外,它可能会损害可读性,因为默认值必须在其他地方解释,而不是简单地在签名中解释。
评论
__annotations__