Если внимательно прочитать, в документации говорится, что:
Если для формата требуется один аргумент, значения могут быть одним объектом, отличным от tuple
. В противном случае значения должны быть tuple
с числом элементов, точно указанным в строке формата, или одним объектом сопоставления (например, словарем).
Теперь в этом случае format
не требует единого аргумента, и поэтому документация говорит нам, что вы должны использовать tuple
или отображение в качестве аргумента; другие случаи попадают в «неопределенное поведение» (что и происходит: поведение не является последовательным во всех случаях).
Это, вероятно, следует считать окончательным ответом на вопрос: если строка не имеет спецификатора формата, использование list
(или любого другого типа, отличного от tuple
или сопоставления) должно просто рассматриваться как ошибка сама по себе, приводящая к неопределенному поведению.
Из этого следует, что вы должны всегда использовать tuple
или dict
в качестве аргумента, иначе вам придется вручную проверять спецификаторы формата или обрабатывать странное поведение.
В вашем случае вы, вероятно, можете решить проблему, используя (['string'], )
вместо ['string']
.
Возможное «объяснение» того, почему результирующее поведение кажется таким случайным:
Похоже, что в исходной реализации PyString_Format
/PyUnicode_Format
вместо использования PyMappingCheck
была ошибка check. в этой строке:
if (PyMapping_Check(args) && !PyTuple_Check(args) &&
!PyObject_TypeCheck(args, &PyBaseString_Type))
dict = args;
Был использован этот код:
if (Py_TYPE(args)->tp_as_mapping && !PyTuple_Check(args) &&
!PyObject_TypeCheck(args, &PyBaseString_Type))
dict = args;
что не эквивалентно. Например, set
не имеет установленного tp_as_mapping
(по крайней мере, в исходном коде Python2.7.3, который я скачал несколько недель назад), а list
устанавливает его.
Это может быть причиной того, что list
(и, возможно, другие объекты) не вызывают TypeError
, в то время как set
, int
и многие другие делают это.
Как я уже говорил ранее в этом же ответе, я получаю TypeError
даже с list
s:
$ python2
Python 2.7.3 (default, Sep 26 2012, 21:53:58)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 'some string' % []
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: not all arguments converted during string formatting
Это, вероятно, показывает, что вышеуказанная проблема здесь не единственная.
Глядя на исходный код, я согласен с тем, что теоретически количество аргументов не проверяется, если аргумент не является кортежем, но это будет означать 'some string' % 5 -> 'some string'
, а не TypeError
, так что должно быть что-то подозрительное в этом коде.
person
Bakuriu
schedule
13.12.2012
jython2.2.1
поднимаетTypeError
- person mgilson   schedule 13.12.2012