Python如何将字节转换为float?

时间:2018-05-18 10:02:06

标签: python python-3.x character-encoding

我有以下代码段:

#!/usr/bin/env python3

print(float(b'5'))

哪个打印5.0没有错误(在Linux上使用utf-8编码)。我很惊讶它不会出错,因为Python不应该知道字节对象使用了什么编码。

有什么见解?

1 个答案:

答案 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让其更新。