如何每次都创建一个新的默认参数列表 [英] How to make a new default argument list every time
问题描述
我有以下设置:
def returnList(arg=["abc"]):
return arg
list1 = returnList()
list2 = returnList()
list2.append("def")
print("list1: " + " ".join(list1) + "\n" + "list2: " + " ".join(list2) + "\n")
print(id(list1))
print(id(list2))
输出:
list1: abc def
list2: abc def
140218365917160
140218365917160
我可以看到arg = [ abc]返回相同默认列表的副本,而不是每次都创建一个新列表。
I can see that arg=["abc"] returns copy of the same default list rather than create a new one every time.
我尝试做过
def returnList(arg=["abc"][:]):
和
def returnList(arg=list(["abc"])):
是否有可能获得新列表,还是每次需要某种默认值时都必须在方法内复制列表?
Is it possible to get a new list, or must I copy the list inside the method everytime I want to some kind of default value?
推荐答案
我见过的最好的模式就是
The nicest pattern I've seen is just
def returnList(arg=None):
if arg is None: arg = ["abc"]
...
唯一的潜在问题是,如果您期望 None
在这里是有效输入,那么在这种情况下,您将不得不使用其他哨兵值
The only potential problem is if you expect None
to be a valid input here which in which case you'll have to use a different sentinel value.
您的方法存在的问题是 arg
的默认参数仅被评估一次。您做什么复制操作都没有关系,因为它只是经过评估而不是与函数一起存储。
The problem with your approach is that arg
s default argument is evaluated once. It doesn't matter what copying operators you do because it's simply evaluated than stored with the function. It's not re-evaluated during each function call.
更新:
我不希望nneonneo发表评论错过了,使用一个新鲜的对象
作为一个哨兵将很好地工作。
I didn't want nneonneo's comment to be missed, using a fresh object
as a sentinel would work nicely.
default = object()
def f(x = default):
if x is default:
...
这篇关于如何每次都创建一个新的默认参数列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!