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]
精彩评论