V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
codists
V2EX  ›  Python

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

  •  
  •   codists ·
    codists · 2022-05-23 11:41:11 +08:00 · 2809 次点击
    这是一个创建于 919 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一、问题描述

    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”指“二进制补码”?

    三、说明

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

    19 条回复    2022-06-02 17:19:46 +08:00
    stein42
        1
    stein42  
       2022-05-23 12:10:28 +08:00
    list 里面存的是指针,指针可以指向任意类型的对象,缺点是每个对象需要单独分配内存。

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

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

    一个 bytes (byte string) 就是一片连续的内存,array.frombytes 就是根据 array 的类型来解释这一片内存。
    sujin190
        2
    sujin190  
       2022-05-23 13:50:49 +08:00
    这个简单的就是 python 的基本数据结构都有需要 python 虚拟机可以理解的头,比如常用的 int32 加上 python 数据结构的头基本都有 28 字节了,100 个 int32 数组就是 2800 字节,machine values 自然指的就是数组保存去掉 python 的头啊,100 个 int32 就是 400 字节
    codists
        3
    codists  
    OP
       2022-05-23 14:54:55 +08:00
    @sujin190
    “听君一席话 如听一席话”——请问你和一楼的大佬真的看懂问题了吗? pthon 官方文档说的是“将字符串追加到 array 中,字符串会被解释为由 machine values 构成的 array”。
    而按照你的意思“machine values 自然指的就是数组保存去掉 python 的头啊”,那么代入进去就是“将字符串追加到 array 中,字符串会被解释为由去掉 Python 头的数组构成的 array”,试问把这个写到官方文档去有几个看得懂?说话带点逻辑吧。ball ball 你们了!
    liangch
        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])
    ```
    codists
        5
    codists  
    OP
       2022-05-23 16:27:43 +08:00
    @liangch
    如果你觉得一楼没有问题,那么请给“machine value”下定义,到底什么是"machine value"?
    stein42
        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))
    XIVN1987
        7
    XIVN1987  
       2022-05-24 11:22:34 +08:00
    感觉是指的大小端,,x86 、ARM 一般是小端,,据说 Power 是大端
    XIVN1987
        8
    XIVN1987  
       2022-05-24 11:36:51 +08:00
    另外,,这个 frombytes 方法名实在误导,,从名称上完全看不出有 append 的意思,,
    改成 append_frombytes 比较好,,
    penguinWWY
        9
    penguinWWY  
       2022-05-24 13:02:53 +08:00
    @codists machine value 就是指数据在内存中的表示啊,前几楼说的没啥问题
    codists
        10
    codists  
    OP
       2022-05-24 16:28:04 +08:00
    @penguinWWY
    1.“但英文版里面用 C 语言的数组做比喻,意思是“machine values”指“二进制补码”——请问你看了我这句话了吗?
    2.不要说什么前几楼说的没啥问题,如果你觉得没有问题,那么请给“machine value”下定义— —what's machine value"?并给这样定义的理由与示例,谢谢。
    stein42
        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" 和 "二进制补码" 不一样,一个是值,一个是值的表示方法,并且只有 "有符号整数" 用 "补码" 表示。

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

    至于中译本就不评价了。
    FYFX
        12
    FYFX  
       2022-05-25 09:45:50 +08:00
    其实你这种情况应该去看一下 CPython 的源码里面关于 array.frombytes 的具体实现
    codists
        13
    codists  
    OP
       2022-05-25 10:47:48 +08:00
    @FYFX
    “听君一席话 如听一席话”— —1 楼建议我去学习 C 语言,然后你建议我去看源码,请问还有什么没建议的?
    FYFX
        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 语言了
    penguinWWY
        15
    penguinWWY  
       2022-05-25 13:30:48 +08:00
    @codists 内存表示和二进制补码不是一个东西

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

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

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

    “计算机科学与技术”专业毕业的人不知道内存表示和补码不是一码事?不会 C 语言? CSAPP 没看过?毕业挺好,下次不要毕业了。
    rev1si0n
        19
    rev1si0n  
       2022-06-02 17:19:46 +08:00
    @penguinWWY 我看合着大家回答没啥问题啊,但是整个就一网络喷子的作风,其实我还是比较赞同你说的 machine value 为内存表示了,不同机器 /大小端,不同平台表示也可能不同。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4125 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 05:18 · PVG 13:18 · LAX 21:18 · JFK 00:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.