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

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

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

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

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

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

5 ответов

Решение

Принимая документацию для id() является правильным и CPython (x86) возвращает адрес объекта, максимальное значение, которое может быть возвращено, составляет 232-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 до 232-1. Обратите внимание, что видимый в приложении адрес может не соответствовать конкретному адресу физической памяти из-за использования виртуальной памяти.

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

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

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

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

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

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

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

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

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.

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

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

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

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

Другие вопросы по тегам