Это известная ошибка ^ H ^ H ^ Hfeature. Согласно документам :
"" "... значение None записывается как пустая строка. [Snip] Все другие нестроковые данные перед записью преобразуются в str ()." ""
Не полагайтесь на преобразования по умолчанию. Используйте repr()
для поплавков. unicode
объекты нуждаются в специальной обработке; см. руководство Проверьте, примет ли получатель файла формат по умолчанию datetime.x
объектов для x in (datetime, date, time, timedelta).
Обновление
Для объектов с плавающей точкой "%f" % value
является , а не хорошей заменой repr(value)
. Критерий - может ли потребитель файла воспроизвести исходный объект с плавающей точкой. repr(value)
гарантирует это. "%f" % value
нет.
# Python 2.6.6
>>> nums = [1323494016.855676, 1323493818.004238, 198.8514380455017, 1.0 / 3]
>>> for v in nums:
... rv = repr(v)
... fv = "%f" % v
... sv = str(v)
... print rv, float(rv) == v, fv, float(fv) == v, sv, float(sv) == v
...
1323494016.8556759 True 1323494016.855676 True 1323494016.86 False
1323493818.0042379 True 1323493818.004238 True 1323493818.0 False
198.85143804550171 True 198.851438 False 198.851438046 False
0.33333333333333331 True 0.333333 False 0.333333333333 False
Обратите внимание, что в приведенном выше примере отображается при проверке полученных строк, что ни один из %f
случаев не работал. До версии 2.7 Python repr
всегда использовал 17 значащих десятичных цифр. В 2.7 это было изменено на использование минимального количества цифр, которое все еще гарантировало float(repr(v)) == v
. Разница составляет , а не ошибка округления.
# Python 2.7 output
1323494016.855676 True 1323494016.855676 True 1323494016.86 False
1323493818.004238 True 1323493818.004238 True 1323493818.0 False
198.8514380455017 True 198.851438 False 198.851438046 False
0.3333333333333333 True 0.333333 False 0.333333333333 False
Обратите внимание на улучшенные результаты repr()
в первом столбце выше.
Обновление 2 в ответ на комментарий "" "И спасибо за информацию о Python 2.7. К сожалению, я ограничен до 2.6.2 (работает на целевом компьютере, который не может быть обновлен) Но я буду помнить это для будущих сценариев. "" "
Это не имеет значения. float('0.3333333333333333') == float('0.33333333333333331')
производит True
на всех версиях Python. Это означает, что вы можете написать свой файл на 2.7, и он будет читать то же самое на 2.6, или наоборот. В точности нет изменений в том, что repr(a_float_object)
производит.