【问题标题】:Default value in a function in Python [duplicate]Python中函数的默认值[重复]
【发布时间】:2011-01-19 18:18:10
【问题描述】:

我注意到以下几点:

class c:
  def __init__(self, data=[]):
    self._data=data
a=c()
b=c()
a._data.append(1)
print b._data
[1]

这是正确的行为吗?

【问题讨论】:

标签: python default-value


【解决方案1】:

是的,这是正确的行为。

但是,从您的问题来看,这似乎不是您所期望的。

如果您希望它符合您的期望,请注意以下事项:

规则 1. 不要使用可变对象作为默认值。

def anyFunction( arg=[] ):

不会创建新的列表对象。 arg 的默认列表对象将在所有地方共享。

同样

def anyFunction( arg={} ):

不会创建新的 dict 对象。此默认字典将被共享。

class MyClass( object ):
    def __init__( self, arg= None ):
        self.myList= [] if arg is None else arg 

这是提供默认参数值的常用方法,默认参数值是一个新的空列表对象。

【讨论】:

  • Will never work. 有点苛刻。 Won't give you a new empty mutable object on each call,似乎更平衡了一些。如果你知道会发生这种情况,你可能真的想使用这种行为。
  • @MattH:通过默认值重用同一个可变对象非常奇怪,以至于无法找到合理的用例。这是一个 default 值,因此它可能(或可能不)被使用,具体取决于客户端对接口的使用。很难诊断出这个问题,所以我坚持我原来的说法。特别是对于 n00bz。
  • 您应该添加一个如何解决此问题的示例。否则答案是好的和正确的。
  • 几乎所有东西都有一个合理的用例。对于可变的默认值,我会选择一个简单的记忆策略,例如 Alex Martelli 在这里描述的:stackoverflow.com/questions/1651154/…
  • @Scott Griffiths:虽然有一个用例,但我会讨论“明智的”。是的,它有效,但不可读的意大利面条代码也是如此。使用可变对象作为 default 值是个坏主意。在示例问题中,默认值语法用于提供隐藏的记忆上下文;它不符合“默认”的通常设计模式,因为提供实际值是合理的。
【解决方案2】:

这是一个典型的陷阱。请参阅http://zephyrfalcon.org/labs/python_pitfalls.html,第 5 节:“可变默认参数”

【讨论】:

    【解决方案3】:

    那么总是做这样的函数:

    def __init__ ( self, data = None ):
        if data is None:
           data = []
    
        self._data = data
    

    或者您也可以使用data = data or [],但这会阻止用户传递参数(''0False 等)。

    【讨论】:

    • 当然你也可以if not data: data = [].
    • 您的示例 data = data or [] 适用于传递空列表。你会说data 将是[] or [],所以它会查看第一个值并看到它的评估结果为“false”,然后它会采用另一个值。
    • 我知道,我的意思是当你传递False 时,[] 将被用作值,尽管你传递了False
    猜你喜欢
    • 2011-06-18
    • 2022-01-03
    • 1970-01-01
    • 2011-09-23
    • 1970-01-01
    • 2015-03-15
    • 2014-02-10
    • 1970-01-01
    • 2021-07-27
    相关资源
    最近更新 更多