Какое наибольшее число Python 2. * x86 (т.е. 32-битная) функция id () в Windows x64 может вернуть? - PullRequest
0 голосов
/ 13 января 2012

Какое наибольшее число может вернуть функция Python 2.6 x86 id()?

Я предполагаю, что верхний предел должен быть объемом памяти, который может видеть любое 32-разрядное приложение, и должен быть: 2 32 , т. Е. 4294967296?

(что было бы неплохо, поскольку я должен соответствовать этому значению в типе C #, для которого было бы достаточно UInt32 или CLS-совместимое Int64, что является причиной моей обеспокоенности, хотя и не имеет отношения к вопросу.)

Но что, если я работаю на Windows x64 с более чем 2 ГБ памяти, скажем, 32 ГБ памяти - возможно ли для функции id() Python, даже если сам интерпретатор Python - x86, вернуть значение выше 2 32 ???

Я предполагаю, что это сводится к представлению интерпретатора Python о машине - я думаю, что WoW64 преобразует 64-битные адреса памяти в 32-битные адреса - но я только догадываюсь - я должен быть уверен!

Ответы [ 5 ]

18 голосов
/ 13 января 2012

Из связанной документации :

Возвращает (...) целое (или длинное целое)

В Python 2.x на amd64 длинное целое число представляет собой целое число больше 64 бит. В любом случае, в Python целые числа не ограничены. Следовательно, id может возвращать произвольно длинные значения .

Если вам необходимо знать определенное максимальное значение, вы можете предположить, что доступная память на вашей платформе является верхней границей размера целого числа, которое вы получаете. Поэтому я бы указал 2 2 32 для 32-разрядных и 2 2 64 для 64 архитектур. Поэтому в случае реализации Python x86 можно с достаточной уверенностью установить верхнюю границу 2 2 32 .

cpython (самая популярная реализация python) действительно возвращает адреса памяти (builtin_id в Python/bltinmodule.c):

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

Это будет 32-битное / 64-битное значение, но поведение - это подробности реализации , как явно указано в документации. По определению, программист не должен полагаться на детали реализации.

Я сильно сомневаюсь, что существует законный вариант использования идентификаторов, а тем более перенос их в другую программу. Вместо этого вы должны использовать пользовательскую таблицу объектов или просто передать набор. Если вы намереваетесь использовать Python вместе с C #, ironpython позволяет вам делать это в том же коде.

2 голосов
/ 16 января 2012
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, а максимальный идентификатор (), которого я достиг, - 1460876200.

1 голос
/ 22 января 2012

При условии, что документация для 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.Обратите внимание, что видимый в приложении адрес может не соответствовать конкретному адресу физической памяти из-за использования виртуальной памяти .

1 голос
/ 16 января 2012

Windows будет запускать приложение в среде (32 или 64-разрядной), для которой оно было скомпилировано , а не в ЦП, на котором оно работает.Например, компьютер x64 под управлением Windows 7 будет запускать 32-разрядный python в 32-разрядной среде.

Таким образом, для запуска python, скомпилированного для x86, всегда будет использоваться 32-разрядное адресное пространство, что означает, что id()всегда будет возвращать значение, которое отображается на уникальный 32-битный указатель.(Обратите внимание, что реализация может делать некоторые странные вещи, такие как соление указателя или использование 64-битных или что-то в этом роде.)

1 голос
/ 13 января 2012

Ваши предположения кажутся разумными, но я понятия не имею, верны ли они.

Если вам нужно полагаться на поведение, которое является деталью реализации (т.е. не указано в документации), и вам нужно быть уверенным , тогда я думаю, единственное, что нужно сделать, это прочитать Исходный код используемой версии и узнайте, что он делает.

...