Неожиданное поведение метода id - PullRequest
3 голосов
/ 09 ноября 2019

Проще говоря, почему этот код возвращает False, а не true:

a = 10
print(id(a) is id(a)) # why false?

id () возвращает целое число, и те же самые целочисленные переменные указывают на один и тот же целочисленный объект. Почему тогда возвращается false? Какая разница с:

a = 10
b = 10
print(a is b) # it returns True

Спасибо за объяснение.

Ответы [ 2 ]

2 голосов
/ 09 ноября 2019

Потому что, хотя верно, что

a is a

id(a) является большим целым числом и не сравнивается по is

>>> a = 10
>>> print(id(a) is id(a))
False
>>> print(id(a),id(a))
(44337068, 44337068)
>>>

Проверка https://docs.python.org/2/c-api/int.html#c.PyInt_FromLongдля которых целые числа сравниваются на is - но помните, что это деталь реализации, поэтому не полагайтесь на нее (всегда сравнивайте целые числа с ==):

>>> a = 256
>>> b = 256
>>> a is b
True
>>> a = 257
>>> b = 257
>>> a is b
False

(из "is"Оператор неожиданно ведет себя с целыми числами )

Для дальнейшей мотивации всегда использовать ==, следующее:

a = 300
b = 300
print(a is b)
print(a is 300)
def c(a): return a is 300
def d(a): return a is b
print(c(a))
print(d(a))

при сохранении в файл и запуске печатает True,True, False и True ...

0 голосов
/ 09 ноября 2019

Если вы попытались сделать, например,

 print(str(id(id(a))) + " " + str(id(id(a))))
In [54]: print(str(id(id(a))) + " " + str(id(id(a))))
2460780951888 2460780951888

In [55]: print(str(id(id(a))) + " " + str(id(id(a))))
2460780951472 2460780951472

In [56]: print(str(id(id(a))) + " " + str(id(id(a))))
2460782062320 2460782062320

In [57]: print(str(id(id(a))) + " " + str(id(id(a))))
2460780951888 2460780951888

In [58]: print(str(id(id(a))) + " " + str(id(id(a))))
2460782473392 2460782475664

, который бы каждый раз возвращал новый идентификатор для большого целого числа

Как упоминает @thebjorn, большие целые числа не кэшируютсяВ интерпретаторе Python все время остаются живыми только целые числа от -5 до 256 (в реализации CPython).

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

...