ValueError: требуется больше, чем 2 значения для распаковки в Python 2.6.6
Я получаю ошибку: ValueError: вам нужно больше, чем 2 значения для распаковки
когда я запускаю unit test сейчас, поэтому 2 отказа и один пропустить
теперь, насколько я читал о
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]
приведет к с, содержащему [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.
-------------------- → begin capture stdout < < ---------------------
\ test_many_errors.test_assert_one... FAIL test_many_errors.test_one... ok test_many_errors.test_assert_two... ОШИБКА test_many_errors.test_two... ok test_many_errors.test_value_one... ОШИБКА test_many_errors.test_value_two... SKIP: (, ValueError(),) test_many_errors.test_good_one... ok test_many_errors.test_good_two... ok
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
/
--------------------- → end capture stdout < < ----------------------
Ran 3 тесты в 1.263s
Ответы
Ответ 1
Вместо распаковки в вашем задании:
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]
Ответ 2
Итак, errors
- это список, содержащий элементы, которые являются кортежами длины 2 или 3. Вам нужен способ распаковать корты переменной длины в цикле for. Как вы уже отметили, в Python2 нет чистого способа сделать это. Вместо того, чтобы придумать умный способ реализации этого поведения, я бы предложил убедиться, что список ошибок всегда содержит кортежи длиной 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
Ответ 3
Вы можете написать функцию утилиты, чтобы сделать ваши результаты единообразными:
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)
Ответ 4
Я предлагаю добавить список к необходимой длине с элементами None
:
data = give_me_list()
(val1, val2, val3) = data + (3 - len(data)) * [None]
3 - количество значений левой стороны. Если в списке могут быть избыточные элементы, используйте защиту от этого:
data = give_me_list()[:3]
(val1, val2, val3) = data + (3 - len(data)) * [None]