开发者

ValueError: need more than 2 values to unpack in Python 2.6.6

开发者_C百科

i am getting error: ValueError: need more than 2 values to unpack when i run the unit test now, so 2 failures and one skip now as far as i have read about

lambda i: get_error_count(self._error_lookup, i))

line 142 of source is the method

for test, err, capt in errors:

which has the line of code:

count = get_error_count(i)

reference Python 3.0 has something a bit like this. Excess values can be bound (as a list) to the last variable:

a,b,*c = [1,2,3,4,5]

will result in c containing [3,4,5].

In Python 2.x, you can't do that directly, but you should be able to create a function that lengthens or shortens an input tuple of arguments to the correct length so you can do:

a,c,b = fix(1,2)
d,e,f = fix(1,2,3,4)

However, the function won't know the length of the left hand side sequence, so it will have to be passed in as an extra parameter or hard coded.

so the

count = get_error_count(i)
uses only one variable, where as
def get_error_count(lookup, index):
takes on 2

What should i use as the second variable ? to fix this ?

Thanks, -Kamal.

-------------------- >> begin captured stdout << ---------------------

\ test_many_errors.test_assert_one ... FAIL test_many_errors.test_one ... ok test_many_errors.test_assert_two ... ERROR test_many_errors.test_two ... ok test_many_errors.test_value_one ... ERROR 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 captured stdout << ----------------------


Ran 3 tests in 1.263s


Instead of unpacking in your assignment:

a, b, c = do_something()

Try assigning the result to a single variable and testing its length:

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]


So errors is a list that contains items that are tuples of length 2 or 3. You want a way to unpack tuples of varying length in a for-loop. As you have noted, there is no clean way to do this in Python2. Rather than coming up with a clever way of implementing this behavior, I would suggest making sure that your errors list always contains tuples of length of 3. This can be done every time you add an item to errors, or after the fact, like this:

errors = [(x[0], x[1], x[2]) if len(x) == 3 else (x[0], x[1], None) for x in errors]

Or you could make a generator (which goes against my advice of not finding clever way to implement this behavior):

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

Use it like this:

>>> 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


You could write a utility function to make your results uniform:

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)


I suggest complementing the list to the necessary length with the None elements:

data = give_me_list()
(val1, val2, val3) = data + (3 - len(data)) * [None]

3 is the number of the left hand side values. If the list can have excessive elements, then use protection against that:

data = give_me_list()[:3]
(val1, val2, val3) = data + (3 - len(data)) * [None]
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜