【发布时间】:2015-03-04 16:44:58
【问题描述】:
Python 2.7.5 collections.defaultdict 似乎仅在您将 default_factory 作为位置参数传递时才有效——当您将其作为命名参数传递时它会中断。
如果您运行以下代码,您会看到 default_dict_success() 运行良好,但 default_dict_failure() 会抛出 KeyError。
from collections import defaultdict
test_data = [
('clay', 'happy'),
('jason', 'happy'),
('aj', 'sad'),
('eric', 'happy'),
('sophie', 'sad')
]
def default_dict_success():
results = defaultdict(list)
for person, mood in test_data:
results[mood].append(person)
print results
def default_dict_failure():
results = defaultdict(default_factory=list)
for person, mood in test_data:
results[mood].append(person)
print results
default_dict_success()
default_dict_failure()
输出是
# First function succeeds
defaultdict(<type 'list'>, {'sad': ['aj', 'sophie'], 'happy': ['clay', 'jason', 'eric']})
# Second function fails
Traceback (most recent call last):
File "test_default_dict.py", line 26, in <module>
default_dict_failure()
File "test_default_dict.py", line 21, in default_dict_failure
results[mood].append(person)
KeyError: 'happy'
有人知道怎么回事吗?
编辑:最初我以为我正在查看一些 Python 源代码,这些源代码表明我正在尝试做的事情是可能的,但评论者指出我错了,因为这个对象是用 C 实现,因此没有 Python 源代码。所以它并不像我想象的那样相当神秘。
话虽如此,这是我第一次在 Python 中遇到不能通过名称传递的位置参数。这种事情在其他地方会发生吗?有没有办法在纯 Python(而不是 C 扩展)中实现强制这种行为的函数?
【问题讨论】:
-
你在哪里找到这个
__init__方法?defaultdict是 implemented in C。 -
从 Python 2 和 3 的文档中也可以清楚地看出它是位置参数:
class collections.defaultdict([default_factory[, ...]]) -
@AshwiniChaudhary -- 这是真的。我认为这个问题可以更笼统一些——在什么情况下你可以通过关键字调用位置参数(因为有时你可以:-)。
-
@AshwiniChaudhary 我在我的 IDE (PyCharm) 中使用了“Go To Declaration”...看起来该文件可能是通过 PyCharm 对可执行 C 代码的内省生成的——这是在顶部文件: # from path/to/lib/python2.7/lib-dynload/_collections.so # by generator 1.130
-
@mgilson 我猜不可能用 C 级别编写的函数,通常是那些接受
PyObject *args和/或PyObject *kwds的函数。
标签: python parameters arguments defaultdict