ValueError:在Python 2.6.6中解包需要超过两个值
我在运行单元测试时遇到了一个错误:ValueError: 需要更多的值来解包,所以有两个测试失败了,一个被跳过了。根据我所了解的情况,
lambda i: get_error_count(self._error_lookup, i))
源代码的第142行是这个方法。
for test, err, capt in errors:
里面有一行代码:
count = get_error_count(i)
参考 Python 3.0 有点像这样。多余的值可以作为列表绑定到最后一个变量上:
a,b,*c = [1,2,3,4,5]
这样会导致 c 里面包含 [3,4,5]。
在 Python 2.x 中,你不能直接这样做,但你可以创建一个函数,把输入的参数元组调整到正确的长度,这样你就可以这样做:
a,c,b = fix(1,2) d,e,f = fix(1,2,3,4)
不过,这个函数并不知道左边变量的长度,所以必须把它作为额外的参数传入,或者直接写死在代码里。
所以,
count = get_error_count(i) uses only one variable, where as def get_error_count(lookup, index): takes on 2
我应该用什么作为第二个变量来解决这个问题呢?
谢谢,
-Kamal。
-------------------- >> 开始捕获的标准输出 << ---------------------
\ test_many_errors.test_assert_one ... 失败 test_many_errors.test_one ... 成功 test_many_errors.test_assert_two ... 错误 test_many_errors.test_two ... 成功 test_many_errors.test_value_one ... 错误 test_many_errors.test_value_two ... 跳过: (, ValueError(), ) test_many_errors.test_good_one ... 成功 test_many_errors.test_good_two ... 成功
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/Current/bin/nosetests", line 10, in <module>
sys.exit(run_exit())
File "/Library/Frameworks/Python.framework/Versions/6.3/lib/python2.6/site-packages/nose/core.py", line 117, in __init__
**extra_args)
File "/Library/Frameworks/Python.framework/Versions/6.3/lib/python2.6/unittest.py", line 817, in __init__
self.runTests()
File "/Library/Frameworks/Python.framework/Versions/6.3/lib/python2.6/site-packages/nose/core.py", line 196, in runTests
result = self.testRunner.run(self.test)
File "/Library/Frameworks/Python.framework/Versions/6.3/lib/python2.6/site-packages/nose/core.py", line 63, in run
result.printErrors()
File "/NOSE_TRIM/nosetrim-read-only/nosetrim/nosetrim.py", line 136, in printErrors
lambda i: get_error_count(self._error_lookup, i))
File "/NOSE_TRIM/nosetrim-read-only/nosetrim/nosetrim.py", line 142, in printErrorList
for test, err, capt in errors:
ValueError: need more than 2 values to unpack
/
--------------------- >> 结束捕获的标准输出 << ----------------------
总共运行了 3 个测试,耗时 1.263 秒
4 个回答
你可以写一个工具函数来让你的结果保持一致:
def do_something2():
return 1, 2
def do_something3():
return 1, 2, 3
def do_something5():
return 1, 2, 3, 4, 5
def uniform_result(*args):
return args[0], args[1], args[2:]
a, b, c = uniform_result(*do_something2())
print a, b, c
# 1 2 ()
a, b, c = uniform_result(*do_something3())
print a, b, c
# 1 2 (3,)
a, b, c = uniform_result(*do_something5())
print a, b, c
# 1 2 (3, 4, 5)
这里的 errors
是一个列表,里面的每个项目都是长度为2或3的元组。你想在一个循环中解包这些不同长度的元组。正如你所注意到的,在Python2中没有简单的方法来做到这一点。与其想出一个聪明的办法来实现这个功能,我建议你确保你的 errors 列表里的元组长度始终为3。这可以在你每次添加项目到 errors
时做到,或者事后处理,比如这样:
errors = [(x[0], x[1], x[2]) if len(x) == 3 else (x[0], x[1], None) for x in errors]
或者你可以创建一个生成器(这有点违背我之前的建议,不要找聪明的方法来实现这个功能):
def widen_tuples(iter, width, default=None):
for item in iter:
if len(item) < width:
item = list(item)
while len(item) < width:
item.append(default)
item = tuple(item)
yield item
这样使用:
>>> errors = [(1, 2), (1, 2, 3)]
>>> for a, b, c in widen_tuples(errors, 3):
... print a, b, c
1 2 None
1 2 3
a, b, c = do_something()
t = do_something()
# t is now a tuple (or list, or whatever was returned) of results
if len(t) > 2:
# Can use the third result!
c = t[2]
与其在赋值时拆开变量,不如试着把结果赋值给一个单独的变量,然后检查这个变量的长度。