2014-01-30 4 views
1

Когда я пытаюсь следующий неправильный код:Вводят `ValueError` на плохое форматирование в Python 2.7

not_float = [1, 2, 3] 
"{:.6f}".format(not_float) 

я получаю следующее заблуждение ValueError:

ValueError: Unknown format code 'f' for object of type 'str' 

Это вводит в заблуждение, так как это может сделать я думаю, not_float - это строка. Такое же сообщение встречается для других non_float типов, таких как NoneType, tuple и т. Д. У вас есть идея, почему? И: Должен ли я ожидать этого сообщения об ошибке независимо от типа non_float, если он не предоставляет какой-либо метод форматирования для f?

С другой стороны, пытаясь:

non_date = 3 
"{:%Y}".format(non_date) 

приносит

ValueError: Invalid conversion specification 

который является менее информативным, но и менее вводит в заблуждение.

+1

См. Http://bugs.python.org/issue13790 –

ответ

5

str.format() метод и функция format(), вызовите метод .__format__() объектов, которые пропускают в, проходя по всем после : толстой кишки (.6f в данном случае).

По умолчанию object.__format__() реализация этого метода заключается в вызове str(self), а затем применить format() к такому результату. Это реализуется в C, но в Python, что бы выглядеть следующим образом:

def __format__(self, fmt): 
    return format(str(self), fmt) 

Именно этот вызов, который бросает исключение. Для list объекта, например:

>>> not_float.__format__('.6f') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: Unknown format code 'f' for object of type 'str' 

, потому что это функционально то же самое, как:

>>> format(str(not_float), '.6f') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: Unknown format code 'f' for object of type 'str' 

Целые имеют реализацию пользовательских .__format__ вместо; он не использует str() внутри, потому что существуют варианты форматирования целочисленного размера. Он превращает значение в строку по-разному. В результате это вызывает другое исключение, поскольку оно не распознает %Y как допустимую строку форматирования.

Сообщение об ошибке, безусловно, может быть улучшено; open Python bug обсуждает эту проблему. Из-за изменений в том, как все это работает, проблема уже не проблема в Python 3.4; если строка формата пуста .__format__() больше не будет вызываться.

+0

Замечательный ответ. Знаете ли вы, что привело к ошибке «ValueError: Invalid conversion specification» в секундах? – Bach

+0

@HansZauber: '(3) .__ format __ ('% Y')', потому что метод 'int .__ format __()' не распознает эту строку формата. –

Смежные вопросы