Python array 文档里面的 machine values 具体指的是什么?

2022-05-23 11:41:11 +08:00
 codists

一、问题描述

Python 官方文档在 array — Efficient arrays of numeric values 里面写到:

array.frombytes(s) Appends items from the string, interpreting the string as an array of machine values (as if it had been read from a file using the fromfile() method).

请问各位大佬,machine values 在这里指的是什么?

二、其它资料

《 Fluent Python 》(P59)里面提到 array 时稍微补充说明了一下: For example, if you need to store 10 million floating-point values, an array is much more efficient, because an array does not actually hold full-fledged float objects, but only the packed bytes representing their machine values—just like an array in the C language.

该书中译本翻译为:比如,要存放 1000 万个浮点数的话,数组(array)的效率要高得多,因为数组在背后存的并不是 float 对象,而是数字的机器翻译,也就是字节表述。这一点就跟 C 语言中的数组一样。

《 Fluent Python 》中译本用的是“数字的机器翻译”,单从字面意思我还是猜不出来是啥。但英文版里面用 C 语言的数组做比喻,意思是“machine values”指“二进制补码”?

三、说明

劳烦各位大佬解答时最好提供参考资料,谢谢啦。

2845 次点击
所在节点    Python
19 条回复
stein42
2022-05-23 12:10:28 +08:00
list 里面存的是指针,指针可以指向任意类型的对象,缺点是每个对象需要单独分配内存。

array 直接在一块连续的内存存对应的值,所有的值只能是同一类型。

建议学一下 C 语言,了解 int 、float 这些类型怎么在内存里表示的。(参考 CSAPP)

一个 bytes (byte string) 就是一片连续的内存,array.frombytes 就是根据 array 的类型来解释这一片内存。
sujin190
2022-05-23 13:50:49 +08:00
这个简单的就是 python 的基本数据结构都有需要 python 虚拟机可以理解的头,比如常用的 int32 加上 python 数据结构的头基本都有 28 字节了,100 个 int32 数组就是 2800 字节,machine values 自然指的就是数组保存去掉 python 的头啊,100 个 int32 就是 400 字节
codists
2022-05-23 14:54:55 +08:00
@sujin190
“听君一席话 如听一席话”——请问你和一楼的大佬真的看懂问题了吗? pthon 官方文档说的是“将字符串追加到 array 中,字符串会被解释为由 machine values 构成的 array”。
而按照你的意思“machine values 自然指的就是数组保存去掉 python 的头啊”,那么代入进去就是“将字符串追加到 array 中,字符串会被解释为由去掉 Python 头的数组构成的 array”,试问把这个写到官方文档去有几个看得懂?说话带点逻辑吧。ball ball 你们了!
liangch
2022-05-23 15:13:59 +08:00
一楼讲得有啥问题

```
numbers = array.array('i', [1,3,5,7, 1, 2])
print(numbers)
numbers.frombytes(b'\x08\x00\x00\x00')
print(numbers)
```

```
array(‘i’, [1, 3, 5, 7, 1, 2])
array(‘i’, [1, 3, 5, 7, 1, 2, 8])
```
codists
2022-05-23 16:27:43 +08:00
@liangch
如果你觉得一楼没有问题,那么请给“machine value”下定义,到底什么是"machine value"?
stein42
2022-05-23 16:31:14 +08:00
# 这里的 string 是指字节串(bytes)而不是字符串(str)。
# machine values 就是值(例如 int 、float 等)的机器表示(内存表示)。
# 内存里面每个位有 0 和 1 两种状态,通常每 8 位组成 1 个字节,每个字节取值 0~255 。
# 同一块内存可以按不同的方式来解释。
# tobytes 和 frombytes 功能相反。

import array

# 现代 CPU 都是用补码表示有符号整数
# 大端序和小端序 CPU 结果不同
# int 通常为 32 位,每个 int 对应 4 个字节
a = array.array('i', [-1, 0, 1, 10])
b = a.tobytes()
print(b)
print(list(b))

# 相同的内存可以按不同的类型来解释,结果不同。
c = array.array('i')
c.frombytes(b)
print(c)

d = array.array('I')
d.frombytes(b)
print(d)

# 浮点数按 IEEE 754 标准来表示
# float 为 32 位,每个 float 对应 4 个字节
e = array.array('f', [-1.0, -0.0, 0.0, 1.0, 10.0])
f = e.tobytes()
print(f)
print(list(f))
XIVN1987
2022-05-24 11:22:34 +08:00
感觉是指的大小端,,x86 、ARM 一般是小端,,据说 Power 是大端
XIVN1987
2022-05-24 11:36:51 +08:00
另外,,这个 frombytes 方法名实在误导,,从名称上完全看不出有 append 的意思,,
改成 append_frombytes 比较好,,
penguinWWY
2022-05-24 13:02:53 +08:00
@codists machine value 就是指数据在内存中的表示啊,前几楼说的没啥问题
codists
2022-05-24 16:28:04 +08:00
@penguinWWY
1.“但英文版里面用 C 语言的数组做比喻,意思是“machine values”指“二进制补码”——请问你看了我这句话了吗?
2.不要说什么前几楼说的没啥问题,如果你觉得没有问题,那么请给“machine value”下定义— —what's machine value"?并给这样定义的理由与示例,谢谢。
stein42
2022-05-25 00:44:11 +08:00
value (值)是指整数值(1, 2, 3 ...),实数值(0.1, 1.0, 10.0, ...)、布尔值(true, false)等。
值都有对应的类型,类型可以看做值的集合。

machine value (机器值)是指机器(计算机 CPU)能够直接处理的值。

machine value 可以简单的用几个字节表示,例如:
无符号整数(8 位,16 位,32 位,64 位等),采用原码表示。32 位无符号整数取值范围为 0 到 2**32-1 。
有符号整数(8 位,16 位,32 位,64 位等),采用补码表示。32 位有符号整数取值范围为 -2**31 到 2**31-1 。
浮点数(32 位,64 位等),按 IEEE 754 标准规定的方法表示。32 位浮点数取值范围大约为 -3.4028235e+38 到 3.4028235e+38 ,以及 3 个特殊值。

machine value 的基本运算(加减乘除等)通常就是一条机器指令,这些运算与数学上的运算有些差异,有溢出、误差等情况。

详细可以参考 CSAPP 的第二章。

与 machine value 对应的就是高级语言里的值。
例如 python 里面的 int ,可以表示很大的整数(取决于内存大小)。
每个 int 占用的内存不固定,绝对值越大占用内存越多。
对应的运算也是一个复杂的函数,最终需要很多条机器指令。

----------------

《 Fluent Python 》里的 "just like an array in the C language" 这一句是指:
python 的 array 和 c 里面的 array 是一样的,都是用一块连续的内存来存储多个 machine value 。
例如长度为 10 的 32 位有符号整数数组,就是用连续的 40 个字节来存储,每 4 个字节(32 位)表示 1 个整数。

----------------

python 文档里 "interpreting the string as an array of machine values" 是指:
把 bytes (若干字节)看作 machine value 的数组,类型取决于调用 frombytes 的 array 对象。

----------------

"machine values" 和 "二进制补码" 不一样,一个是值,一个是值的表示方法,并且只有 "有符号整数" 用 "补码" 表示。

----------------

至于中译本就不评价了。
FYFX
2022-05-25 09:45:50 +08:00
其实你这种情况应该去看一下 CPython 的源码里面关于 array.frombytes 的具体实现
codists
2022-05-25 10:47:48 +08:00
@FYFX
“听君一席话 如听一席话”— —1 楼建议我去学习 C 语言,然后你建议我去看源码,请问还有什么没建议的?
FYFX
2022-05-25 11:03:59 +08:00
@codists https://github.com/python/cpython/blob/main/Modules/arraymodule.c
array.frombytes 实现就是里面的 frombytes 函数,函数里面主要逻辑就这句 memcpy(self->ob_item + old_size * itemsize,buffer->buf, n * itemsize),剩下的你该去学 C 语言了
penguinWWY
2022-05-25 13:30:48 +08:00
@codists 内存表示和二进制补码不是一个东西

arraymodule.c 里的实现就是从一个 PyBuffer 里 memcpy 了数据,fromfile 的实现是直接调用了 frombytes ,所以内存中如何表示,array 就如何存储,这么解释不明白?

“an array of machine values”指的就是存在多个元素,那么用每个元素的内存表示,组合成一个数组。

所以楼上让你学 C 语言还真说对了
codists
2022-05-25 13:39:43 +08:00
@penguinWWY
按照你的意思“machine value”指“内存表示”,那么请问你,什么是内存表示,字符串的内存表示是啥?数字的内存表示是啥?请举例。
codists
2022-05-25 13:56:24 +08:00
@penguinWWY
还是说你所谓的“内存表示”已经没有单词表达了,必须用“machine value”这种及其少见的单词表示?作为一个“计算机科学与技术”专业毕业的人,看到这种“建议学 C 语言,然后自己看源码”的建议,我只能说完美闭环,建议很好,下次不要建议了,谢谢。
penguinWWY
2022-05-30 11:27:41 +08:00
@codists 合着你知道”machine value“不是一个常见的用法?这本来就不算是一个专业术语,我们帮你推测验证它的具体含义,然后你说没有给出定义?要饭要的这么理直气壮的吗?

“计算机科学与技术”专业毕业的人不知道内存表示和补码不是一码事?不会 C 语言? CSAPP 没看过?毕业挺好,下次不要毕业了。
rev1si0n
2022-06-02 17:19:46 +08:00
@penguinWWY 我看合着大家回答没啥问题啊,但是整个就一网络喷子的作风,其实我还是比较赞同你说的 machine value 为内存表示了,不同机器 /大小端,不同平台表示也可能不同。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/854656

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX