Python 2.6的x86 id()
函数可以返回的最高数字是什么?
我认为上限必须是任何32位应用程序可以看到的内存量必须是:2 32 ,即4294967296?
(这可以,因为我必须在UInt32
或符合CLS的Int64
就足够的C#类型中使用此值,这是我关注的原因,尽管与此无关问题。)
但是如果我在Windows x64上运行的内存超过2GB并说内存为32GB,那么Python的id()
功能是否可行,即使Python解释器本身是x86,返回一个高于2 32 ???
我猜它归结为Python解释器对机器的看法 - 我想WoW64将64位内存地址转换为32位地址 - 但我只是猜测 - 我需要确定!
答案 0 :(得分:18)
返回(...)整数(或长整数)
在amd64的Python 2.x中,长整数是大于64位的整数。无论如何,在Python中,整数是无界的。因此,id
可以返回任意长的值。
如果必须知道确定的最大值,则可以假设平台上的可用内存是您获得的整数大小的上限。因此,我为32位指定了2 2 32 ,对于64种架构,我指定了2 2 64 。在x86 python实现的情况下,可以合理放心地将上边界置于2 2 32 。
cpython(最流行的python实现)确实会返回一个内存地址(builtin_id
中的Python/bltinmodule.c
):
static PyObject * builtin_id(PyObject *self, PyObject *v) {
return PyLong_FromVoidPtr(v);
}
这将是一个32位/ 64位值,但行为是实现细节,正如文档中明确说明的那样。根据定义,程序员不能依赖于实现细节。
我强烈怀疑有一个合法的用例永远使用ID,更不用说将它们转移到另一个程序了。相反,您应该使用自定义对象表,或者只是传输一组。如果您打算将Python与C#结合使用,ironpython允许您使用相同的代码执行此操作。
答案 1 :(得分: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.
答案 2 :(得分:1)
你的猜测看似合理,但我不知道它们是否正确。
如果您需要依赖于实现细节的行为(即未在文档中指定),并且您需要确定,那么我想唯一要做的就是阅读您正在使用的版本的源代码,并找出它的作用。
答案 3 :(得分:1)
Windows将在编译的环境(32位或64位)中运行应用程序,而不是运行它的CPU。例如,运行Windows 7的x64计算机将在32位环境中运行32位python。
因此,运行为x86编译的python将始终使用32位地址空间,这意味着id()
将始终返回映射到唯一32位指针的值。 (注意,实现可能会做一些奇怪的事情,如盐化指针或使用64位或类似的一些疯狂的东西。)
答案 4 :(得分: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之间的地址。请注意,由于使用了virtual memory,应用程序中可见的地址可能与特定的物理内存地址不对应。