LINUX.ORG.RU

Числа в Python


0

0

Может кто сталкивался с этим и объяснит мне, как реализованы числовые
объекты в Python? И логично объяснит зачем сделано именно так.

[Примеры для Python 2.3.5 [GCC 3.3.5]]

Я так понимаю, что числа неизменяемые объекты. Если мы делаем a += 1,
то a после этого просто будет указывать на новый объект:

  >>> a = 1
  >>> id (a)
  135523760
  >>> a += 1
  >>> id (a)
  135523748

Но, насколько я знаю, в текущих реализациях Python индивидуальность -
это адрес объекта. А для 4-х милионов чисел это накладно... И что мы
видим - а то, что индивидуальность различна только для числовых объектов
от -5 до 99:

  >>> id (-7)
  135591764
  >>> id (-6)
  135591764
  >>> id (-5)
  135523832
  ...
  >>> id (0)
  135523772
  >>> id (1)
  135523760
  >>> id (2)
  135523748
  ...
  >>> id (98)
  135524572
  >>> id (99)
  135524560
  >>> id (100)
  135591764
  >>> id (10000)
  135591764

Т. е. для каждого из чисел от -5 до 99 индивидуальность - 
ФИКСИРОВАННОЕ постоянное число. Для остальных - это некоторое
НЕФИКСИРОВАННОЕ одинаковое число.

НЕФИКСИРОВАННОЕ, т. к.:
  >>> id (1000)
  135591764
  >>> id (1001)
  135591764
  >>> a = 1000
  >>> id (a)
  135591764
  >>> id (1000)
  135591716
  >>> id (1001)
  135591716
  >>> a = a + 1
  >>> id (a)
  135591740
  >>> id (1000)
  135591764

Более того:
  >>> id (1000)
  135591728
  >>> a = 1000
  >>> id (a)
  135591728
  >>> id (1000)
  135591740
  >>> b = 1000
  >>> id (b)
  135591740
  >>> a is b
  False
  >>> a == b
  True

Т. о. равные числа могут быть разными объектами. Несколько
протеворечит книге Романа Сузи по Python: "[про индивидуальность]
для простейших встроенных типов (числа, строки) индивидуальность
определяется значением.", хотя, учитывая, что она написана для более
ранних версий Python, может оно так и было - я пока не проверял...

[Дальнейшие примеры для Python 2.4 в Windows, для Линукса у меня пока нет]

В Python 2.4 все изменилось. Теперь при проверке последовательных
сколь угодно больших чисел одинаковых значений id выявить не удалось.
Хотя логика подсказывает, что они должны будут повториться через
какие-то большие промежутки.

>>> for i in xrange (1000):
	for j in xrange (1000):
		if (i != j) and (id (i) == id (j)):
			print i, j

не выдало ничего. Но так все стало на свои места при последующих
экспериментах. Такое поведение характерно для ручного ввода в
интерактивном режиме id (xxx) и для созданных при генерации с помощью
range или xrange. Следующий код вернул все на свои места:

>>> for i in xrange (-20, 100):
	for j in xrange (-20, 100):
		if (i != j) and (id (i + 1) == id (j + 1)):
			print i + 1, j + 1

выводило все пары с числами вне диапазона [-5, 99]. То есть та же
картина.

А теперь собственно то, ради чего я затеял топик - кто нибудь это все
объяснит или придется самому копать код Python?

P. S. Может хотя бы кто-нибудь поделится подобными наблюдениями?

Я думаю, что старые числа выкинул garbage collector. И на их место встали новые. Поэтому id совпали. Попробуй сохранять их где-то хотя бы.

smartly ★★★
()
Ответ на: комментарий от smartly

Это я понимаю, у меня не стоит проблема сохранения этих чисел, я хотел
узнать, может кто знает ЗАЧЕМ сделано исключение для чисел от -5 до 99,
и почему оно завуалировано (ИМЕННО ЗАВУАЛИРОВАНО) в версии 2.4. Я просто
не очень люблю всяческие исключения и умолчания. Поэтому хотел знать,
есть ли объективные причины для их наличия.

Спасибо.

satanic-mechanic
() автор топика
Ответ на: комментарий от satanic-mechanic

> ЗАЧЕМ сделано исключение для чисел от -5 до 99

Скорее всего, какие-то модули хранят на них ссылки, поэтому GC их не выкидывает. Думаю, если покопаться по модулям, то найдутся ещё подобные числа.

watashiwa_daredeska ★★★★
()

Читайте книжки! Объекты для чисел меньше 100 из-за частого использования в целях оптимизации зашиты стаитчески. Две единицы -- это одно и то же. Два числа по 1000 -- это разное.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.