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]