Python 2.7中format()抛ValueError:非字符串输入为何仍报str格式错误?
Python 2.7下
SingleLineGrooveTable.formatve函数格式化错误排查与修复 问题描述
使用Python 2.7编写单元测试时,调用SingleLineGrooveTable.formatve([3.1423])抛出*ValueError: Unknown format code 'f' for object of type 'str'*错误,明明传入的是列表而非字符串,却找不到问题根源。
相关代码
目标类代码
class SingleLineGrooveTable: VEFMT = '.3f' @classmethod def formatve(cls, value, error=None): er = 0 if error is not None: er = error v = value elif len(value) > 1: v, er = value else: v = value return format(v, cls.VEFMT), format(er, cls.VEFMT)
测试代码
import unittest class TestSingleLineGrooveTable(unittest.TestCase): def test_formatve_no_error(self): e_v = '3.142' e_er = '0.000' r_v, r_er = SingleLineGrooveTable.formatve([3.1423]) self.assertEqual(e_v, r_v) self.assertEqual(e_er, r_er)
问题根源
当传入[3.1423]时,函数进入else分支:v = value,这里的v被直接赋值为整个列表[3.1423],而非列表内的浮点元素。在Python 2.7中,对列表调用format()函数时,列表会被隐式转换为字符串(例如变成'[3.1423]'),此时用浮点格式符.3f去格式化字符串,就会触发上述ValueError。
修复方案
修改else分支的逻辑,取出列表中的唯一元素赋值给v:
class SingleLineGrooveTable: VEFMT = '.3f' @classmethod def formatve(cls, value, error=None): er = 0 if error is not None: er = error v = value elif len(value) > 1: v, er = value else: # 取出列表的第一个元素作为v v = value[0] return format(v, cls.VEFMT), format(er, cls.VEFMT)
修改后,传入[3.1423]时,v会被赋值为浮点值3.1423,er保持为0,调用format()时能正常完成浮点格式化,测试用例可顺利通过。
注:若需要兼容空列表的极端情况,可以在
else分支前增加非空判断,但根据原代码的调用逻辑,应该默认传入的列表至少包含一个元素。
内容的提问来源于stack exchange,提问作者Réka
相关产品推荐
相关产品推荐

