我有以下代码片段:
#!/usr/bin/env python3
print(float(b'5'))
在Linux上使用utf-8编码,以下哪个会打印5.0
而不会出错?我很惊讶它没有报错,因为Python不应该知道bytes对象使用了什么编码方式。有什么见解吗?
我有以下代码片段:
#!/usr/bin/env python3
print(float(b'5'))
在Linux上使用utf-8编码,以下哪个会打印5.0
而不会出错?我很惊讶它没有报错,因为Python不应该知道bytes对象使用了什么编码方式。bytes
对象时,float()
函数将把该对象的内容视为ASCII字节。这在这里已经足够了,因为从字符串到浮点数的转换只接受ASCII数字和字母,以及.
和_
(唯一允许的非ASCII码点是空格码点),而这与int()
函数处理bytes
输入的方式类似。PyNumber_Float()
方法(对于str
对象,代码直接跳转到PyFloat_FromString
函数)。PyNumber_Float()
检查是否存在__float__
方法,但如果该方法不存在,则调用PyFloat_FromString()
函数。PyFloat_FromString()
不仅接受str
对象,还接受实现缓冲区协议的任何对象。在Python 2中,String
名称是保留的,而在C实现中,Python 3的str
类型称为Unicode
。bytes
对象实现了缓冲区协议,并使用PyBytes_AS_STRING
宏来访问保存字节的内部C缓冲区。_Py_string_to_number_with_underscores()
和float_from_string_inner()
的内部函数组合将ASCII字节解析为浮点值。对于实际的str
字符串,CPython实现实际上会通过仅查看输入值中的ASCII码点并将任何非ASCII空格字符转换为ASCII 0x20空格的方式将任何非ASCII字符串转换为ASCII字节序列,然后使用相同的_Py_string_to_number_with_underscores()
/ float_from_string_inner()
组合。
我认为这是文档中的错误,并已向Python项目提交了问题报告以进行更新。
\x00
字节不会被接受。这些字节必须是ASCII码,并符合float()
字符串解释规则。 - Martijn Pieters
float()
的文档显示它可以接受一个字符串、一个数字或者一个实现了__float__
方法的类型。bytes
没有实现__float__
方法。 - Martijn Pietersb'5'
不遵循这个规则吗?虽然这应该在文档中明确说明。 - Mazdakbytes
类型不被视为字符串。 - Martijn Pieters