我有以下代码段:
#!/usr/bin/env python3
print(float(b'5'))
哪个打印5.0
没有错误(在Linux上使用utf-8编码)。我很惊讶它不会出错,因为Python不应该知道字节对象使用了什么编码。
有什么见解?
答案 0 :(得分:11)
传递bytes
对象时,float()
将对象的内容视为ASCII字节。这里就足够了,因为从字符串到float的转换只接受ASCII数字和字母,加上.
和_
无论如何(唯一允许的非ASCII代码点是空白代码点) ,这类似于int()
处理bytes
输入的方式。
在幕后,实施方法是这样做的:
PyNumber_Float()
(对于str
个对象,代码会直接跳转到PyFloat_FromString
。)PyNumber_Float()
检查__float__
方法,但如果该方法不可用,则会调用PyFloat_FromString()
PyFloat_FromString()
不仅接受str
个对象,还接受任何object implementing the buffer protocol个对象。 String
名称是Python 2保留,Python 3 str
类型在C实现中称为Unicode
。bytes
个对象实现缓冲区协议,PyBytes_AS_STRING
macro用于访问保存字节的内部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()
组合。
我将此视为文档中的错误,并filed issue with the Python project让其更新。