开发者

Python dict.get() behavior when first arg exists but *default* doesn't

So, I have some code which contains a dictionary, and I do some validation on the dictionary. The validation rule is basically that the dictionary may contain either a 'to' key, or a 'to[]' key. Whichever one it contains, I need the value back so I can check the length against the length of another key in the dictionary.

I've actually found a better way to solve the immediate problem, but in working through this I came across a curious behavior in Python 2.7.1, which implies that a dict.get() doesn't work the way I thought, so I'm looking for some clarification before I go diving into the C implementation of a dictionary, which I'm in no particular rush to do :)

The short summary version is that it seems that if you pass a default value into .get(), Python attempts to evaluate that default even if the first argument is a valid key in the dictionary.

Here's an example:

>>> toparm = 'to'
>>> toarrparm = 'to[]'
>>> d = {toparm: 'foo'}
>>> d.get(toarrparm, [d[toparm]])
['foo']
>>> d = {toarrparm: ['foo', 'bar']}
>>> d.get(toarrparm, [d[toparm]])
Traceback (most recent call last):
  File "<input>", line 1, in <module>
KeyError: 'to'
>>开发者_运维技巧;> d
{'to[]': ['foo', 'bar']}
>>> toarrparm
'to[]'
>>> sys.version
'2.7.1 (r271:86882M, Nov 30 2010, 10:35:34) \n[GCC 4.2.1 (Apple Inc. build 5664)]'
>>> d['to[]'] = ['foo', 'bar', 'baz']
>>> d
{'to[]': ['foo', 'bar', 'baz']}
>>> d.get(toarrparm)
['foo', 'bar', 'baz']
>>> d.get(toarrparm, [d[toparm]])
Traceback (most recent call last):
  File "<input>", line 1, in <module>
KeyError: 'to'
>>> d
{'to[]': ['foo', 'bar', 'baz']}
>>> d['to'] = 'foo'
>>> d.get(toarrparm, [d[toparm]])
['foo', 'bar', 'baz']
>>> 

If this behavior is old news, can someone explain why that would be? Should I just always ask for the thing I think isn't there first? What if I really don't know which one will be there? Just fall back to try/except? Have I missed something else?


Arguments to a function or method are always evaluated before the function is called. If you don't want this then use a sentinel object instead of the expression as the default.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜