0

Python 2.6 的 x86id()函数可以返回的最大数字是多少?

我认为上限必须是任何 32 位应用程序可以看到的内存量,它必须是:2 32,即 4294967296?

(这很好,因为我必须将此值拟合到 C# 类型中,UInt32或者符合 CLSInt64就足够了,这是我担心的原因,尽管与问题无关。)

但是,如果我在具有超过 2GB 内存的 Windows x64 上运行,比如 32GB 内存——id()即使 Python 解释器本身是 x86,Python 的函数是否有可能返回高于 2 32的值?

我猜它归结为 Python 解释器对机器的看法——我想 WoW64 将 64 位内存地址转换为 32 位地址——但我只是在猜测——我需要确定!

4

5 回答 5

18

链接的文档

返回 (...) 一个整数(或长整数)

在 amd64 上的 Python 2.x 中,长整数是大于 64 位的整数。无论如何,在 Python 中,整数是无界的。因此,id可以返回任意长的值

如果您必须知道一个明确的最大值,您可以假设您平台上的可用内存是您获得的整数大小的上限。因此,我会为 32 位指定 2 2 32 ,为 64 位架构指定 2 2 64。在 x86 python 实现的情况下,因此可以有合理的信心将上边界放置在 2 2 32处。

cpython(最流行的 python 实现)确实会返回一个内存地址(builtin_idin Python/bltinmodule.c):

static PyObject * builtin_id(PyObject *self, PyObject *v) {
    return PyLong_FromVoidPtr(v);
}

这将是一个 32 位/64 位值,但行为是一个实现细节,如文档中明确说明的那样。根据定义,程序员不能依赖实现细节。

我强烈怀疑是否存在使用 ID 的合法用例,更不用说将它们转移到另一个程序了。相反,您应该使用自定义对象表,或者只是转移一组。如果您打算将 Python 与 C# 结合使用,ironpython允许您在相同的代码中执行此操作。

于 2012-01-13T01:52:03.000 回答
2
def func(n):
    max=0L
    for i in range(n):
        x=id(i)
        if x > max : max=x
    return max

for i in range(32):
    x=0L
    try:
        x=func(2**i)
        print '{0: 10}{1: 15}{2: 15}'.format(i,2**i,x)
    except:
        print '{0: 10}{1: 15}{2:>15}'.format(i,2**i,'error')

我认为实际上 id() 可以达到的最大值是 2**32 但实际上它从未达到如此高的数字。我在 32 位架构中尝试了上面的代码。如果我在理解您的问题时犯了任何错误,请告诉我。

4294967296L 是 2^32,我达到的最大 id() 是 1460876200。

于 2012-01-16T09:53:53.167 回答
1

你的猜测似乎很合理,但我不知道他们是否正确。

如果您需要依赖作为实现细节的行为(即未在文档中指定),并且您需要确定,那么我想唯一要做的就是阅读您正在使用的版本的源代码并找出它的作用。

于 2012-01-13T02:16:05.140 回答
1

Windows 将在为其编译的环境(32 位或 64 位)中运行应用程序,而不是在其运行的 CPU 上运行。例如,运行 Windows 7 的 x64 计算机将在 32 位环境中运行 32 位 python。

因此,运行为 x86 编译的 python 将始终使用 32 位地址空间,这意味着id()将始终返回一个映射到唯一 32 位指针的值。(请注意,实现可能会做一些奇怪的事情,比如加盐指针或使用 64 位或类似的一些疯狂的事情。)

于 2012-01-16T03:44:40.370 回答
1

假设文档id()正确且 CPython (x86) 返回对象的地址,则可以返回的最大值为 2 32 -1 (4294967295)。这可以用一个简单的 C 程序来演示:

#include <stdio.h>

int main(void) {
    void* p = 0;          // specify a pointer at 0
    p = ~p;               // invert all bits
    uintptr_t x = p;      // convert to an integer type fo the same size
    printf("%lu\n", x);
    return 0;
}

无论底层操作系统如何,这都是正确的,使用 32 位指针类型编译的应用程序只能指定 0 到 2 32 -1 之间的地址。请注意,由于使用了虚拟内存,应用程序中可见的地址可能与特定的物理内存地址不对应。

于 2012-01-22T17:04:40.140 回答