【问题标题】:Default array parameters unexpectedly not empty [duplicate]默认数组参数意外不为空[重复]
【发布时间】:2011-12-19 16:25:03
【问题描述】:

可能重复:
“Least Astonishment” in Python: The Mutable Default Argument

def stackdemo(stack=[]):
  stack.append('q')
  return stack

stackdemo()
print stackdemo()

返回['q','q'],而

stackdemo([])
print stackdemo([])

使用相同的函数只返回['q'],正如预期的那样。

如果使用默认值,为什么 Python 似乎会重用数组?我错过了什么吗?

【问题讨论】:

    标签: python arrays optional-parameters


    【解决方案1】:

    列表是一个可变对象。来自doc

    默认值只计算一次。当默认值是可变对象(例如列表、字典或大多数类的实例)时,这会有所不同。

    使用None

    def stackdemo(stack=None):
        if stack is None:
            stack = []
        stack.append('q')
        return stack
    
    stackdemo()
    print stackdemo()
    

    【讨论】:

    • 单行,更清晰的if 块版本:stack = stack or []
    • @JCotton - 这是错误的。想象一下使用之前定义的l = [](并在其他地方使用)调用stackdemo(l)
    • 你是对的,尽管单线可能适用于 OP 的情况。 stackdemo(mystr)mystr="" 或其他类似的 False 值也是错误的。这取决于stack 变量的用途和意义。如果 None 的值具有单独的含义,或者变量可以包含其他有效但为 False 的值,则无法替代显式的 is None 检查。
    【解决方案2】:

    在 Python 中,变量是通过对象引用而不是值传递的。

    这意味着在这种情况下,您正在修改 stack=[] 变量。

    如果您想避免这种行为,则必须在函数中生成变量,因为在这种情况下它将在运行时生成。

    def stackdemo(stack=None):
        if stack is None:
            stack = []
        ...
    

    【讨论】:

    • 第一行实际上并不正确。阅读this
    • @JBernardo:这是正确的,但取决于您对价值的定义。由于我省略了“对象”部分,因此可能有点不清楚。我会澄清一点:)
    猜你喜欢
    • 1970-01-01
    • 2011-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-21
    • 2017-03-06
    • 1970-01-01
    相关资源
    最近更新 更多