Czytając uważnie, dokumentacja stwierdza, że:
Jeśli Format wymaga jednego argumentu, wartości mogą być pojedynczym nie- tuple
przedmiot. W przeciwnym razie wartości muszą być tuple
o dokładnie takim numerze elementów określonych przez ciąg formatu lub pojedynczy obiekt odwzorowania (na przykład słownik).
Teraz, w tym przypadku format
nie wymaga jednego argumentu, a tym samym dokumentacja mówi nam, że należy użyć tuple
lub mapowanie jako argumentu; inne przypadki należą do "niezdefiniowanego zachowania" (co się dzieje: zachowanie nie jest spójne we wszystkich przypadkach).
Prawdopodobnie powinno to być uznane za ostateczną odpowiedź na pytanie: jeśli ciąg nie ma żadnego specyfikatora formatu, użycie go jako list
(lub innego rodzaju niż tuple
lub odwzorowanie) powinno być po prostu uważane za błąd sam w sobie prowadzący do niezdefiniowane zachowanie.
Z tego wynika, że powinieneś zawsze użyć tuple
lub dict
jako argumentu, w przeciwnym razie trzeba sprawdzić dla formatu specyfikatorami obsługiwać ręcznie lub zachowań nieparzyste.
W twoim przypadku prawdopodobnie możesz rozwiązać problem, używając (['string'],)
zamiast ['string']
.
Possible „wyjaśnienie” dlaczego wypadkowa zachowanie wydaje się być tak przypadkowy:
Wydaje się, że nie było buggy check w oryginalnym realizacji PyString_Format
/PyUnicode_Format
, zamiast korzystania PyMappingCheck
na this linii :
if (PyMapping_Check(args) && !PyTuple_Check(args) &&
!PyObject_TypeCheck(args, &PyBaseString_Type))
dict = args;
został użyty ten kod:
if (Py_TYPE(args)->tp_as_mapping && !PyTuple_Check(args) &&
!PyObject_TypeCheck(args, &PyBaseString_Type))
dict = args;
który nie jest równoważny. Na przykład set
nie ma zestawu tp_as_mapping
(przynajmniej w kodzie źródłowym Python2.7.3, który pobrałem kilka tygodni temu), podczas gdy list
ustawia to.
Może to być powodem list
(i ewentualnie inne obiekty) nie podnieść TypeError
chwilę, set
, int
i wiele inni.
Jak stwierdzono wcześniej w tej samej odpowiedzi robię dostać TypeError
nawet 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
To chyba pokazuje, że powyższy problem nie jest jedynym tutaj.
Patrząc na kod źródłowy Zgadzam się, że teoretycznie liczba argumentów nie jest zaznaczone, jeśli argument nie jest krotka, ale to oznaczałoby 'some string' % 5 -> 'some string'
a nie TypeError
, więc to musi być coś podejrzanego w ten kod.
Wygląda mi na nieudokumentowaną "cechę" (błąd). – mgilson
FWIW, 'jython2.2.1' * robi * podnosi' TypeError' – mgilson