Форум сайта python.su
0
a = "string"
b = "string"
print(a is b) #отдаёт True
print(a == b) #отдаёт True
a = ["one", 1, "three-2"]# разное
b = ["one", 1, "three-2"]# разное
def oper(a, b):
if a is b:
print(True)
else:
print(False)
oper(a, b)#отдаёт False
a = b
oper(a, b)#отдаёт True
Офлайн
25
- это конструктор списка:
In [1]: a = 'string'
In [2]: b = 'string'
In [3]: a, id(a), b, id(b)
Out[3]: ('string', 3074100736L, 'string', 3074100736L)
In [4]: a = [1]
In [5]: b = [1]
In [6]: a, id(a), b, id(b)
Out[6]: ([1], 153051884, [1], 153139276)
Офлайн
0
спасибо :) увидел - понял
Офлайн
Учусь по книге Марка Саммерфилда “Программирование на Python 3”, в ней пример:
>>> a = "many paths" >>> b = "many paths" >>> a is b False >>> a == b True
>>> a = "manypaths" >>> b = "manypaths" >>> a is b True
Офлайн
20
mimoВ целях повышения эффективности кода Python делает кэширование малых целых чисел и небольших строк. Хотя проверка a is b возвращает True, можно легко убедиться, что ссылки a и b указывают все же не на один и тот же объект. Если бы a и b указывали на один объект, то при изменении b на какое-либо другое значение точно такое же значение должно было бы получаться у а. Но этого не происходит:
Я задаю то же самое, но без пробела, и получаю следующее:
>>> a = “manypaths”
>>> b = “manypaths”
>>> a is b
True
Почему такие результаты получаются?
>>> x = "hello" >>> y = "hello" >>> x is y True >>> y = "world" >>> print(x) hello
>>> import sys >>> sys.getrefcount("manypaths") 4
>>> sys.getrefcount(2) 112
Отредактировано old_monty (Ноя. 29, 2015 19:30:18)
Офлайн
857
old_montyЭто не так. Если is возвращает True, то они связаны с одним объектом. А кто они? Они - это имена.
Хотя проверка a is b возвращает True, можно легко убедиться, что ссылки a и b указывают все же не на один и тот же объект.
old_montyТы не изменил значение строки y, а создал новую строку и привязал y к ней. И забыл проверить is снова.
Если бы a и b указывали на один объект, то при изменении b на какое-либо другое значение точно такое же значение должно было бы получаться у а. Но этого не происходит:
>>> a = [1] >>> b = a >>> a is b True >>> a [1] >>> b [1] >>> a.append(2) >>> a [1, 2] >>> b [1, 2] >>> a is b True >>>
mimoЭто зависит от интерпретатора, он может оптимизировать, а может не оптимизировать. Так что у автора книги они не оптимизировались, а у тебя оптимизируются. Поэтому строки можно сравнивать только через ==.
Почему такие результаты получаются?
Отредактировано py.user.next (Ноя. 30, 2015 00:27:48)
Офлайн
221
я бы сказал так, оператор is сравнивает Python объекты, а не их значения. Т.е. оператор is не нужно применять в задачах когда нужно сравнить значения двух переменных.
old_montyВот вам из справки по Питону:
Хотя проверка a is b возвращает True, можно легко убедиться, что ссылки a и b указывают все же не на один и тот же объект.
The operators is and is not test for object identity: x is y is true if and only if x and y are the same objectНу и py.user.next вам уже разъяснил вашу ошибку.
Офлайн
20
py.user.next, JOHN_16
Посыпал голову пеплом и ушел читать документацию. 
Офлайн
Так. Мне становится ясно, что ничего не ясно. )
Цитирую Саммерфилда:
“В языке Python нет переменных как таковых - вместо них используются ссылки на объекты. …интерпретатор создает объект, а затем создает ссылку на объект.
Поскольку все переменные в языке Python фактически являются ссылками, иногда возникает необходимость определить, не ссылаются ли две или более ссылок на один и тот же объект. Оператор is - это двухместный оператор, который возвращает True, если ссылка слева указывает на тот же самый объект, что и ссылка справа.
…сравниваются ссылки на объекты, а не сами объекты. Оператор is сравнивает только адреса памяти, в которых располагаются объекты - если адреса равны, следовательно, ссылки указывают на один и тот же объект.”
Python 3.5.0 (v3.5.0:374f501f4567, Sep 13 2015, 02:27:37) [MSC v.1900 64 bit (AMD64)] on win32 Type "copyright", "credits" or "license()" for more information. >>> import sys >>> #пример из книги >>> a = "many paths" >>> b = "many paths" >>> id(a), id(b) #подсмотрено в посте №2 (56237168, 56237232) >>> sys.getrefcount("many paths") #совет из поста №5 2 >>> a is b False >>> a == b True >>> >>> #повторяю без пробела >>> a = "manypaths" >>> b = "manypaths" >>> id(a), id(b) (56236976, 56236976) >>> sys.getrefcount("manypaths") 4 >>> a is b True >>> a == b True
old_monty
Чтобы точно знать, сколько ссылок указывает на данный объект, можно применять функцию getrefcount() из модуля sys
Офлайн