Как ключевое слово " is " реализовано в Python?



... элемент is ключевое слово, которое может быть использовано для равенства в строках.



>>> s = 'str'
>>> s is 'str'
True
>>> s is 'st'
False


Я пытался как __is__() и __eq__() но они не работают.



>>> class MyString:
... def __init__(self):
... self.s = 'string'
... def __is__(self, s):
... return self.s == s
...
>>>
>>>
>>> m = MyString()
>>> m is 'ss'
False
>>> m is 'string' # <--- Expected to work
False
>>>
>>> class MyString:
... def __init__(self):
... self.s = 'string'
... def __eq__(self, s):
... return self.s == s
...
>>>
>>> m = MyString()
>>> m is 'ss'
False
>>> m is 'string' # <--- Expected to work, but again failed
False
>>>
487   10  

10 ответов:

проверка строк с is работает только тогда, когда строки интернируются. Если вы действительно не знаете, что вы делаете и явно интернированы строки, которые вы должны никогда использовать is на струны.

is тесты личность, а не равенство. Это означает, что Python просто сравнивает адрес памяти, в котором находится объект. is в основном отвечает на вопрос "есть ли у меня два имени для одного и того же объекта?" - перегрузка это было бы бессмысленно.

например, ("a" * 100) is ("a" * 100) и ложные. Обычно Python записывает каждую строку в другую ячейку памяти, интернирование в основном происходит для строковых литералов.

The is оператор эквивалентен сопоставлению id(x) значения. id в настоящее время реализуется для использования указателей в качестве сравнения. Так что вы не можете перегрузить , и, насколько мне известно, вы не можете перегрузка id либо.

Итак, вы не можете. Необычное в Python, но это так.

Питон is ключевое слово проверяет идентичность объекта. Вы не должны использовать его для проверки на равенство строк. Может показаться, что это часто работает, потому что реализации Python, как и многие языки очень высокого уровня, выполняют "интернирование" строк. То есть строковые литералы и значения внутренне хранятся в хэшированном списке, а те, которые идентичны, отображаются как ссылки на один и тот же объект. (Это возможно, потому что строки Python неизменный.)

однако, как и в любой детали реализации, вы не должны полагаться на это. Если вы хотите проверить равенство, используйте оператор==. Если вы действительно хотите проверить идентичность объекта, то используйте is --- и мне было бы трудно придумать случай, когда вы должны заботиться о идентификаторе объекта string. К сожалению, вы не можете рассчитывать на то, что две строки каким-то образом "намеренно" идентичны ссылкам на объекты из-за вышеупомянутого интернирования.

The is ключевое слово сравнивает объекты (или, скорее, сравнивает, если две ссылки относятся к одному и тому же объекту).

вот почему, я думаю, нет механизма для обеспечения вашей собственной реализации.

иногда это работает со строками, потому что Python хранит строки "умно", так что при создании двух одинаковых строк они хранятся в одном объекте.

>>> a = "string"
>>> b = "string"
>>> a is b
True
>>> c = "str"+"ing"
>>> a is c
True

вы можете надеяться увидеть ссылку против сравнения данных в простой "копии" пример:

>>> a = {"a":1}
>>> b = a
>>> c = a.copy()
>>> a is b
True
>>> a is c
False

если вы не боитесь испортить байт-код, вы можете перехватить и исправить COMPARE_OP с 8 ("is") аргумент для вызова функции hook на сравниваемых объектах. Посмотри на dis документация модуля для запуска.

и не забудьте перехватить __builtin__.id() Если кто-то будет делать id(a) == id(b) вместо a is b.

не удается сравнить строковую переменную со строковым значением и двумя строковыми переменными, когда строка начинается с '-'. Моя версия Python-2.6.6

>>> s = '-hi'
>>> s is '-hi'
False 
>>> s = '-hi'
>>> k = '-hi'
>>> s is k 
False
>>> '-hi' is '-hi'
True

вы не можете перегрузить is оператора. То, что вы хотите перегрузить это == оператора. Это можно сделать, определив __eq__ метод в классе.

вы используете сравнение идентичности. == - Это, наверное, то, что вы хотите. Исключение - это когда вы хотите проверить, являются ли один элемент и другой точно таким же объектом и в той же позиции памяти. В ваших примерах элементы не совпадают, так как один из них имеет другой тип (my_string), чем другой (string). Кроме того, нет такой вещи, как someclass.__is__ в python (если, конечно, вы не положили его туда сами). Если да, то сравнение объектов с - это не было бы надежным просто сравнить места памяти.

когда я впервые столкнулся с - это ключевое слово, это меня тоже смутило. Я бы так и подумал - это и == не отличались. Они произвели один и тот же вывод из интерпретатора на многих объектах. Этот тип предположения на самом деле именно то, что - это... это за. Это эквивалент python " Эй, не путайте эти два объекта. они разные.", который по сути то, что [кто-то меня поправил сказал. Формулируется совсем по-другому, но одна точка == другая точка.

в для некоторых полезных примеров и некоторого текста, чтобы помочь с иногда запутанными различиями посетите документ от python.org ' s mail host написано "Дэнни ю"

или, если это в автономном режиме, используйте неуказанные сайт Pastebin я сделал из его тела.

в случае, если они, в некоторых 20 или около того синих лун (синие Луны являются реальным событием), оба вниз, я приведу примеры кода

###
>>> my_name = "danny"
>>> your_name = "ian"
>>> my_name == your_name
0                #or False
###

###
>>> my_name[1:3] == your_name[1:3]
1    #or True
###

###
>>> my_name[1:3] is your_name[1:3]
0
###

' is ' сравнивает идентичность объекта, тогда как == сравнивает значения.

пример:

a=[1,2]
b=[1,2]
#a==b returns True
#a is b returns False

p=q=[1,2]
#p==q returns True
#p is q returns True

ошибки утверждения могут легко возникнуть с и ключевое слово при сравнении объектов. Например, объекты a и b может содержать одно и то же значение и использовать один и тот же адрес памяти. Поэтому, делая

>>> a == b

собирается возвращать

True

но если

>>> a is b

оценивает в

False

вы, вероятно, должны проверить

>>> type(a)

и

>>> type(b)

это могут быть другая и причина неудачи.

Comments

    Ничего не найдено.