4
import inspect
class Test:
  def test(self, p, d={}):
    d.update(p)
    return d
print inspect.getargspec(getattr(Test, 'test'))[3]
print Test().test({'1':True})
print inspect.getargspec(getattr(Test, 'test'))[3]

我希望 Test.test 的 argspec 不会改变,但因为 dict.update 它会改变。为什么?

4

2 回答 2

5

因为dicts是可变对象。当你调用时d.update(p),你实际上是在改变字典的默认实例。这是一个常见的问题;特别是,您永远不应该将可变对象用作参数列表中的默认值。

更好的方法如下:

class Test:
    def test(self, p, d = None):
        if d is None:
            d = {}
        d.update(p)
        return d
于 2010-04-28T14:05:13.717 回答
2

Python 中的默认参数是定义函数时设置的任何对象,即使您设置了可变对象。这个问题应该解释这意味着什么以及为什么 Python 是 Python 中最不令人惊讶的 SO 问题:可变的默认参数

基本上,每次调用函数时都使用相同的默认对象,而不是每次都创建一个新副本。例如:

>>> def f(xs=[]):
...   xs.append(5)
...   print xs
... 
>>> f()
[5]
>>> f()
[5, 5]

解决此问题的最简单方法是创建实际的默认参数None,然后简单地检查None并在函数中提供默认值,例如:

>>> def f(xs=None):
...   if xs is None:
...     xs = []
...   xs.append(5)
...   print xs
... 
>>> f()
[5]
>>> f()
[5]
于 2010-04-28T14:06:18.107 回答