将列表对象作为函数参数传递(而不是默认值),是否有任何陷阱?

问题描述 投票:1回答:1

不知道我在哪里阅读这个建议,但如果我需要传递值序列作为函数参数,我使用元组。可能我是这样做的,因为它是不可改变的,我建议通过阅读一些书或通过课程这样做。但是现在我需要一个函数,其中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
python list python-3.x parameter-passing
1个回答
1
投票

如果将可变对象传递给函数,则该函数可以更改内容:

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]

根据经验(有异常),函数应该只修改输入,如果它没有返回任何东西 - 或者如果它确实返回了某些东西,应该保留输入。

© www.soinside.com 2019 - 2024. All rights reserved.