内置函数中的可变默认参数

Dee*_*ace 3 python

我们都知道'可怕的可变默认参数'

我惊讶地发现至少有一个使用可变默认参数的内置函数deepcopy(和相关的__deepcopy__).

def deepcopy(x, memo=None, _nil=[]):

资源

这只是模块作者的一个忽视,还是有一些特殊deepcopy的行为证明了这一点?

Mar*_*ers 5

是的,这是故意的,该对象被用作唯一的标记对象.它永远不会发生变异,也不会检查列表对象内容.它的唯一目的是拥有一个可以在is测试中使用的唯一对象.

更常见的是None用作哨兵来测试是否有东西没有被设置,但有时你需要允许None它是一个有效的设定值.在执行deepcopy()_nil对象时用于替换None:

y = memo.get(d, _nil)
if y is not _nil:
    return y
Run Code Online (Sandbox Code Playgroud)

这允许memo[d] = None设置,如果存在或丢失则memo.get(d)返回:Nonememo[d]

>>> memo = {}; d = 'foo'
>>> _nil = []
>>> memo.get(d) is None
True
>>> memo.get(d, _nil) is _nil
True
>>> memo[d] = None
>>> memo.get(d) is None
True
>>> memo.get(d, _nil) is _nil
False
Run Code Online (Sandbox Code Playgroud)

如果您正在考虑使用自己独特的未定义None对象,那么您可能希望使用它们object().但是object()deepcopy()编写函数时,Python语言中还不存在.

_nil是一个使它成为局部变量的参数.这使得查找_nil引用比模块中的全局更便宜,请参阅为什么Python代码在函数中运行得更快?这是一个可以很容易地调用的函数重要了很多用于复制自定义对象的深度和广度结构时.因此,正如名称的最初下划线所示,_nil是一个实现细节.

另请参阅有没有办法将默认参数设置为等于另一个参数值?