开发者

Does dict.update affect a function's argspec?

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(geta开发者_Python百科ttr(Test, 'test'))[3]

I would expect the argspec for Test.test not to change but because of dict.update it does. Why?


Because dicts are mutable objects. When you call d.update(p), you are actually mutating the default instance of the dict. This is a common catch; in particular, you should never use a mutable object as a default value in the list of arguments.

A better way to do this is as follows:

class Test:
    def test(self, p, d = None):
        if d is None:
            d = {}
        d.update(p)
        return d


A default argument in Python is whatever object was set when the function was defined, even if you set a mutable object. This question should explain what that means and why Python is the SO question least astonishment in python: the mutable default argument.

Basically, the same default object is used every time the function is called, rather than a new copy being made each time. For example:

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

The easiest way around this is to make your actual default argument None, and then simply check for None and provide a default in the function, for example:

>>> def f(xs=None):
...   if xs is None:
...     xs = []
...   xs.append(5)
...   print xs
... 
>>> f()
[5]
>>> f()
[5]
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜