我被下面的例子弄糊涂了:
def append(elem, to=None):
if to is None:
to = []
to.append(elem)
return to
append(5)
# Out: [5]
append(3) # A new list is created
# Out: [3]
这里的重点应该是在每个函数调用的开始处将“to”重置为空列表,以避免以下情况:
append(5)
# Out: [5]
append(3) # A new list is created
# Out: [5, 3]
但是,如何检查“to”是否为None以将其设置为[]?在我看来,你要么拉入定义中定义的“to”,要么拉入上次调用修改的“to”。这是怎么回事?你知道吗
使用默认参数定义函数时,如果未提供该参数,则函数将使用该参数的默认值。因此,在
append(5)
的情况下,没有指定to
,因此函数假定to
的值为None
—实际上与调用append(5, None)
相同。你知道吗所以现在,函数检查
if to is None
,就是这样,所以to
被重新分配到一个空列表。5
附加到列表中,然后返回列表。你知道吗当您进行第二次调用
append(3)
时,又好像您调用了append(3, None)
。同样地,if to is None
计算结果为True
,并且to
被重新分配给空列表。然后,将3
附加到该空列表,并返回该列表。你知道吗由于默认参数(在本例中是
None
)是不可变的,因此to
上的操作不会持久化到函数调用的结尾。函数有自己的内存块,当函数返回时会被清除。你知道吗但是,如果默认参数是可变的(例如
[]
),则在定义函数时会创建该值(即当python看到def func(arg1, arg2=[])
时,它会在内存中创建一个空列表,并在每次调用该函数时使用该列表)。因此,对该列表所做的任何更改都将保留到函数末尾,因为该可变默认参数是在定义函数时创建的(在调用函数之前)。你知道吗我在这里引用Common Gotchas — The Hitchhiker's Guide to Python:
例如:
另外,如果您不喜欢使用none ant,请将其视为antipattern,您可以使用更高级的:
我不知道是不是更好
相关问题 更多 >
编程相关推荐