Default value in a function in Python
我注意到以下情况:
1 2 3 4 5 6 7 8
| class c:
def __init__(self, data=[]):
self._data=data
a=c()
b=c()
a._data.append(1)
print b._data
[1] |
这是正确的行为吗?
- 请阅读标记文档以了解如何正确设置代码格式。它在页面的右侧。请更新您的问题以缩进代码4的空格。
- 相关:stackoverflow.com/questions/1011431/…,stackoverflow.com/questions/1534407/…,stackoverflow.com/questions/1651154/…
是的,这是正确的行为。
然而,从你的问题来看,这似乎不是你所期望的。
如果您希望它符合您的期望,请注意以下几点:
规则1。不要将可变对象用作默认值。
1
| def anyFunction( arg=[] ): |
不会创建新的列表对象。arg的默认列表对象将在各地共享。
同样地
1
| def anyFunction( arg={} ): |
不会创建新的dict对象。将共享此默认dict。
1 2 3
| 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:通过默认值重用同一个可变对象是非常奇怪的,以至于它无法找到一个合理的用例。它是一个默认值,因此根据客户机对接口的使用情况,它可能(也可能不)被用作默认值。用这个诊断问题太难了,所以我坚持我原来的公式。尤其是对于N00BZ。
- 您应该添加一个如何解决这个问题的示例。否则答案是正确的。
- 几乎所有东西都有一个合理的用例。对于可变的默认值,我会选择一个简单的记忆化策略,例如alex martelli在这里描述的:stackoverflow.com/questions/1651154/…
- @ScottGriffiths:虽然有一个用例,但我会争论"明智"。是的,它可以用,但不可读的意大利面条代码也可以用。使用可变对象作为默认值是一个坏主意。在这个示例问题中,默认值语法用于提供隐藏的记忆上下文;它不适合"默认"的常规设计模式,因为没有合理的理由提供实际值。
这是一个典型的陷阱。参见http://zephyrfalcon.org/labs/python_pitfalls.html,第5节:"可变默认参数"
总是这样做,然后:
1 2 3 4 5
| def __init__ ( self, data = None ):
if data is None:
data = []
self._data = data |
或者,您也可以使用data = data or [],但这样可以防止用户传递空参数(''、0、False等)。
- 当然你也可以做if not data: data = []。
- 您的示例data = data or []对于正在传递的空列表来说工作正常。你会说,data将是[] or [],所以它会看第一个,看到它的评估结果是"假",然后它会取另一个值。
- 我知道,我的观点是,当你通过False时,例如,[]将被用作值,尽管你通过False。