2

Почему в Python3 при сравнение идентификатора с самим собой получается False.

id(False)
=> 140076979909600

id(False) is id(False)
=> False

id(False) == id(False)
=> True

x = id(False)
print(x)
139746282587104

x is x
=> True

False is x
=> False

id(False) is x
=> False

id(False) is id(x)
=> False

print(x, id(False))
139746282587104 139746282587104

type(id(False)) is type(id(False))
=> True

type(id(False))
=> <class 'int'>

Идентификатор не меняется, тип не меняется.

Aivengo
  • 140
  • разные объекты - разные идентификаторы – slippyk Jul 11 '17 at 04:36
  • id(False) is id(False), идентификатор это внутренняя ссылка на объект, каждый раз вызывая id(), похоже, создается новый объект типа int, который хранит значение идентификатора, поэтому сравнивать через is не хорошо, используйте тогда оператор ==, который сравнит по значению. type(id(False)) is type(id(False)) равны, потому что type(id(False)) вернет тип int, а у каждого типа идентификатор уникальный и неповторимый – gil9red Jul 11 '17 at 05:51
  • @slippyk объект не меняется, мы сравниваем его с самим собой – Aivengo Jul 11 '17 at 10:45
  • @gil9red но как он может создавать ещё один объект False. Значения id одинаковы, если бы он создавал другой объект, то при сравнение False is False получалось False, но это не так. – Aivengo Jul 11 '17 at 10:50
  • @Aivengo, не False новый создается, а при id(False) создается новый объект типа int, который из id(False) возвращается – gil9red Jul 11 '17 at 11:00
  • @gil9red я не совсем понимаю работу оператора is. При сравнивание объектов id(False) is id(False), сравниваются уже существующие объекты в памяти или функция id создаёт новый объект? – Aivengo Jul 11 '17 at 11:39
  • 2
    @Aivengo, id(False) возвращает значение идентификатора False, например 123456 (тип int), а 123456 это объект со своими методами и свойствами и у него тоже есть идентификатор и делая id(False) is id(False) сравниваются не идентификаторы False. Понятно? – gil9red Jul 11 '17 at 12:07

4 Answers4

3

id() возвращает число (int). Равные числа (==) не обязаны быть представлены одним и тем же объектом (is).

Иначе говоря: id(a) == id(а) (так как a is a), но из равенства значений (что id функция возвращает), не следует идентичность int объектов.

Подробнее, посмотрите связанный (обратный) вопрос: Что такое объект в Python. Почему id(a) == id(b) == id(1)? и ещё о работе is, == для целых чисел в Питоне: Присваивание в Python.

Кратко:

  • не следует оператор is использовать для сравнения чисел
  • используйте == для сравнения целых чисел.
jfs
  • 52,361
1

Давайте посмотрим, что вы делаете:

# Смотрим идентификатор объекта (число)
id(False)  
=> 139746282587104

# Записываем в переменную идентификатор объекта (число)
x = id(False)  
print(x)
=> 139746282587104

# Сравниваем идентификатор объекта сам с собой как объект.
# Смысл данного действия не очень понятен.
x is x  
=> True

# Сравниваем объект False и число (идентификатор объекта), что не имеет смысла.
False is x  
=> False

# Сравниваем идентификатор объекта (число) и идентификатор объекта в переменной (число) как объекты.
# Равенство объектов для одинаковых по значению чисел не гарантируется.
id(False) is x  
=> False

# Сравниваем идентификатор объекта False и идентификатор идентификатора объекта False как объекты.
# Данное сравнение не имеет смысла.
id(False) is id(x)  
=> False

Имеет смысл сравнивать id объектов по равенству или сравнивать сами объекты через is, но сравнивать идентификаторы идентификаторов по равенству значений или сравнивать идентификаторы через is, или идентификатор объекта с самим объектом - не имеет смысла.

insolor
  • 49,104
  • Объясните, пожалуйста, а в чем смысл проверять False is x, если x = id(False)? Это же разные объекты... id(False) вернет тип int, а у False, конечно будет и другой тип, и другой id. Да и id(x) это id(id(False)). Непонятные мне эти манипуляции и чего вы хотели ими показать – gil9red Jul 11 '17 at 05:44
  • @gil9red, ох блин, затупил. – insolor Jul 11 '17 at 05:52
  • @insolor почему при сравнение id(False) is x равенство не гарантируется? Сравнивая одинаковые объекты id(False) is id(False), объект не меняется как и его значения. – Aivengo Jul 11 '17 at 10:56
  • @Aivengo, если объекты одинаковые по значению, это еще не означает, что это один и тот же объект. Насколько я помню, целые числа до 256 включительно все существуют в единственном экземпляре, а вот 257 is (257-1+1) вам вернет False. – insolor Jul 11 '17 at 13:08
0

Идентификаторы как раз и меняются.

is возвращает истину, если оба операнда указывают на один объект.

x = id(False)

Здесь будет создана переменная (объект) x с новым идентификатором, отличным от id(False), но с присвоенным значением идентификатора False.

То есть:

id(False) is id(x)
>>>> False
id(False) == id(x)
>>>> False
id(False) is x
>>>> False

Но:

x == id(False)
>>>> True
slippyk
  • 6,161
  • Спасибо, с x = id(False) разобрался, это разные объекты с схожими значениями. Но почему id(False) is id(False) выходит False? – Aivengo Jul 11 '17 at 11:04
  • вероятно значения, возвращаемые вызовом id() хранятся в разных местах (адресах памяти), поэтому id(False) is id(False) дает результат False, хотя значения одинаковы id(False) == id(False) - True – slippyk Jul 11 '17 at 11:45
  • то есть id(False) сохраняет значение в свою ячейку памяти, второй вызов id(False) сохраняет значение в еще одну ячейку. Т.к. оператор is сравнивает объекты, то и получается False, так как объекты (адреса) разные – slippyk Jul 11 '17 at 11:47
0
# 1==3 создаст ссылку  и свяжет её с 
переменной x возвращаемое 
значение типа bool
x = 1==3
# преобразует 0 к типу bool 0>>False 
1>>True
b = bool(0)
# сравниваем значения ссылок
x is b
True
# возвращаемые значения
b, x
(False, False)
# ну и айди
id(b); id(x)
3069765112
3069765112

Объекты True и False вобщем всегда будут иметь одни айди т.к. они всегда живут в памяти вроде как то так.:)