不知道我在哪里阅读这个建议,但如果我需要传递值序列作为函数参数,我使用元组。可能我是这样做的,因为它是不可改变的,我建议通过阅读一些书或通过课程这样做。但是现在我需要一个函数,其中list应该作为参数传递(因为我需要在其中使用pop
)。而现在当我比以前更有经验时,我只是想知道,作为函数参数传递列表有什么问题吗?
我知道使用列表作为默认值 - 不是一件好事。但是简单的论证呢?是否有任何问题可能发生在它之后,或者我应该遵循的唯一规则 - 不要使用list作为参数默认值?
例如,做这样的事情 - 不是一件好事:
def hello(arg_string="abc", arg_list = []):
print arg_string, arg_list
arg_string = arg_string + "defg"
arg_list.append("A")
for i in range(4):
hello()
输出将是
abc []
abc ['A']
abc ['A', 'A']
abc ['A', 'A', 'A']
但是,如果我想要一些简单的东西,无论是否改变对象,但我在哪里可以确定我可以记录我改变了一些东西:
def hello(arg_list = []):
for i in arg_list:
print(i)
hello(["1","2","3"])
这里的输出是:
1
2
3
如果将可变对象传递给函数,则该函数可以更改内容:
l = [1, 2, 3]
def bad_func(lst):
lst.append(5)
return lst
l2 = bad_func(l)
print(l) # [1, 2, 3, 5]
print(l2) # [1, 2, 3, 5]
通常,函数应指示它们是否改变输入,因此当函数没有或只有差的文档时,这可能只是一个问题。
但是,如果更改输入,则始终可以传入副本或在函数中执行复制:
def well_behaved_func(lst):
lst = lst[:] # shallow copy because the function alters the input
lst.append(5)
return lst
l = [1, 2, 3]
l2 = well_behaved_func(l)
print(l) # [1, 2, 3]
print(l2) # [1, 2, 3, 5]
根据经验(有异常),函数应该只修改输入,如果它没有返回任何东西 - 或者如果它确实返回了某些东西,应该保留输入。