【问题标题】:Passing list objects as function arguments (not as default value), are there any pitfalls?将列表对象作为函数参数(而不是默认值)传递,有什么陷阱吗?
【发布时间】:2017-05-29 16:09:44
【问题描述】:

不知道我在哪里读到这个建议,但如果我需要将值序列作为函数参数传递,我正在使用元组。可能我这样做是因为它是不可变的,我被建议通过阅读一些书或通过课程来这样做。但是现在我需要一个函数,列表应该作为参数传递(因为我需要在其中使用pop)。现在,当我比以前更有经验时,我只是想知道,将列表作为函数参数传递有什么问题吗?

我知道使用列表作为默认值 - 不是一件好事。但是简单的论证呢?之后是否有任何问题,或者我应该遵循的唯一规则 - 不要使用列表作为参数默认值?

例如,做这样的事情 - 不是一件好事:

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 中并不常用。
  • 你是指属性还是参数?属性是. 分配的属性,参数是调用函数时() 中的参数。
  • FWIW,这是我的一个旧答案,它有一个使用函数属性 (func.count) 进行静态存储的函数:stackoverflow.com/a/26501218/4014959
  • @Unbrok3n 没问题,你能不能edit 这个问题,也许包括一个简短的例子,你如何在列表中传递。只是为了让问题在不阅读 cmets 的情况下自我解释?

标签: python list python-3.x parameter-passing


【解决方案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]

根据经验(也有例外),一个函数应该只在它没有返回任何东西时修改输入 - 或者如果它确实返回了一些东西,则应该不理会输入。

【讨论】:

  • 这和函数属性有什么关系?
  • 是的,你是对的。但是如果我只使用列表来循环它或表明我改变了一些东西,那么我不会破坏任何清晰的代码rools?
  • @PM2Ring 有趣,我读的是arguments 而不是attributes。可能是因为问题包含在我期望“参数”的地方,例如:“如果我需要将值序列作为函数属性传递,我正在使用元组”。听起来更像是 OP 错误的属性和参数。不确定...
  • @Unbrok3n 如果您不修改列表,那么绝对没有问题。如果您在函数修改列表之前复制列表,也没有问题。万一你修改了输入意外那么它可能是一个问题(除非你在函数文档中提到它)。
  • 我同意 OP 的描述有点混乱,尤其是关于传递函数属性的内容。这就是为什么我要求他们发布一些代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-14
  • 2016-12-18
  • 1970-01-01
  • 1970-01-01
  • 2022-01-02
  • 1970-01-01
  • 2018-08-17
相关资源
最近更新 更多