Ответ 1
При передаче объекта bytes
float()
обрабатывает содержимое объекта как байты ASCII. Этого достаточно здесь, поскольку преобразование из строки в float допускает только цифры ASCII и буквы плюс .
и _
любом случае (единственными кодовыми точками, отличными от ASCII, которые будут разрешены, являются непрозрачные кодовые точки), и это аналогично тому, как int()
обрабатывает ввод bytes
.
Под капотом реализация выполняет следующее:
- потому что вход не является строкой, на
PyNumber_Float()
(для объектовstr
код перескакивает прямо вPyFloat_FromString
). -
PyNumber_Float()
проверяет метод__float__
, но если он недоступен, он вызываетPyFloat_FromString()
-
PyFloat_FromString()
принимает не только объектыstr
, но и любой объект, реализующий буферный протокол. ИмяString
является удержанием Python 2, типstr
Python 3 называетсяUnicode
в реализации C. -
bytes
реализуют буферный протокол, а макросPyBytes_AS_STRING
используется для доступа к внутреннему буфере C, содержащему байты. - Комбинация двух внутренних функций с именем
_Py_string_to_number_with_underscores()
иfloat_from_string_inner()
затем используется для анализа ASCII-байтов в значение с плавающей запятой.
Для реальных str
строк реализация CPython фактически преобразует любую строку, отличную от ASCII, в последовательность байтов ASCII, только просматривая кодовые точки ASCII во входном значении и преобразуя любой символ пробела без ASCII в ascii 0x20 пробелов, чтобы затем использовать тот же самый _Py_string_to_number_with_underscores()
/float_from_string_inner()
.
Я вижу это как ошибку в документации и подал проблему с проектом Python, чтобы обновить его.