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”指“二进制补码”?
劳烦各位大佬解答时最好提供参考资料,谢谢啦。
1
stein42 2022-05-23 12:10:28 +08:00
list 里面存的是指针,指针可以指向任意类型的对象,缺点是每个对象需要单独分配内存。
array 直接在一块连续的内存存对应的值,所有的值只能是同一类型。 建议学一下 C 语言,了解 int 、float 这些类型怎么在内存里表示的。(参考 CSAPP) 一个 bytes (byte string) 就是一片连续的内存,array.frombytes 就是根据 array 的类型来解释这一片内存。 |
2
sujin190 2022-05-23 13:50:49 +08:00
这个简单的就是 python 的基本数据结构都有需要 python 虚拟机可以理解的头,比如常用的 int32 加上 python 数据结构的头基本都有 28 字节了,100 个 int32 数组就是 2800 字节,machine values 自然指的就是数组保存去掉 python 的头啊,100 个 int32 就是 400 字节
|
3
codists OP @sujin190
“听君一席话 如听一席话”——请问你和一楼的大佬真的看懂问题了吗? pthon 官方文档说的是“将字符串追加到 array 中,字符串会被解释为由 machine values 构成的 array”。 而按照你的意思“machine values 自然指的就是数组保存去掉 python 的头啊”,那么代入进去就是“将字符串追加到 array 中,字符串会被解释为由去掉 Python 头的数组构成的 array”,试问把这个写到官方文档去有几个看得懂?说话带点逻辑吧。ball ball 你们了! |
4
liangch 2022-05-23 15:13:59 +08:00 2
一楼讲得有啥问题
``` 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]) ``` |
5
codists OP @liangch
如果你觉得一楼没有问题,那么请给“machine value”下定义,到底什么是"machine value"? |
6
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)) |
7
XIVN1987 2022-05-24 11:22:34 +08:00
感觉是指的大小端,,x86 、ARM 一般是小端,,据说 Power 是大端
|
8
XIVN1987 2022-05-24 11:36:51 +08:00
另外,,这个 frombytes 方法名实在误导,,从名称上完全看不出有 append 的意思,,
改成 append_frombytes 比较好,, |
9
penguinWWY 2022-05-24 13:02:53 +08:00
@codists machine value 就是指数据在内存中的表示啊,前几楼说的没啥问题
|
10
codists OP @penguinWWY
1.“但英文版里面用 C 语言的数组做比喻,意思是“machine values”指“二进制补码”——请问你看了我这句话了吗? 2.不要说什么前几楼说的没啥问题,如果你觉得没有问题,那么请给“machine value”下定义— —what's machine value"?并给这样定义的理由与示例,谢谢。 |
11
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" 和 "二进制补码" 不一样,一个是值,一个是值的表示方法,并且只有 "有符号整数" 用 "补码" 表示。 ---------------- 至于中译本就不评价了。 |
12
FYFX 2022-05-25 09:45:50 +08:00
其实你这种情况应该去看一下 CPython 的源码里面关于 array.frombytes 的具体实现
|
13
codists OP @FYFX
“听君一席话 如听一席话”— —1 楼建议我去学习 C 语言,然后你建议我去看源码,请问还有什么没建议的? |
14
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 语言了 |
15
penguinWWY 2022-05-25 13:30:48 +08:00
@codists 内存表示和二进制补码不是一个东西
arraymodule.c 里的实现就是从一个 PyBuffer 里 memcpy 了数据,fromfile 的实现是直接调用了 frombytes ,所以内存中如何表示,array 就如何存储,这么解释不明白? “an array of machine values”指的就是存在多个元素,那么用每个元素的内存表示,组合成一个数组。 所以楼上让你学 C 语言还真说对了 |
16
codists OP @penguinWWY
按照你的意思“machine value”指“内存表示”,那么请问你,什么是内存表示,字符串的内存表示是啥?数字的内存表示是啥?请举例。 |
17
codists OP @penguinWWY
还是说你所谓的“内存表示”已经没有单词表达了,必须用“machine value”这种及其少见的单词表示?作为一个“计算机科学与技术”专业毕业的人,看到这种“建议学 C 语言,然后自己看源码”的建议,我只能说完美闭环,建议很好,下次不要建议了,谢谢。 |
18
penguinWWY 2022-05-30 11:27:41 +08:00 1
@codists 合着你知道”machine value“不是一个常见的用法?这本来就不算是一个专业术语,我们帮你推测验证它的具体含义,然后你说没有给出定义?要饭要的这么理直气壮的吗?
“计算机科学与技术”专业毕业的人不知道内存表示和补码不是一码事?不会 C 语言? CSAPP 没看过?毕业挺好,下次不要毕业了。 |
19
rev1si0n 2022-06-02 17:19:46 +08:00
@penguinWWY 我看合着大家回答没啥问题啊,但是整个就一网络喷子的作风,其实我还是比较赞同你说的 machine value 为内存表示了,不同机器 /大小端,不同平台表示也可能不同。
|