... 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
>>>
Проверка строк с помощью -
работает только тогда, когда строки интернированы. Если вы действительно не знаете, что делаете, и явно не интернировали строки, вы не должны никогда использовать is
в строках.
- это
проверка идентичности , а не равенства . Это означает, что Python просто сравнивает адрес памяти, в которой находится объект. is
в основном отвечает на вопрос «Есть ли у меня два имени для одного и того же объекта?» - перегрузка, которая не имела бы смысла.
Например, ("a" * 100) is ("a" * 100)
is False . Обычно Python записывает каждую строку в отдельную ячейку памяти, интернирование в основном происходит для строковых литералов.
Оператор is
эквивалентен сравнению значений id (x)
. id
в настоящее время реализован для использования указателей в качестве сравнения. Таким образом, вы не можете перегрузить - это сам
, и, AFAIK, вы также не можете перегрузить id
.
Итак, вы не можете. Необычно для питона, но вот оно.
Ключевое слово Python -
проверяет идентичность объекта. Вы НЕ должны использовать его для проверки равенства строк. Может показаться, что это часто работает, потому что реализации Python, как и многие языки очень высокого уровня, выполняют «интернирование» строк. То есть строковые литералы и значения внутри хранятся в хешированном списке, а те, которые идентичны, отображаются как ссылки на один и тот же объект. (Это возможно, потому что строки Python неизменяемы).
Однако, как и в случае с любыми другими деталями реализации, вам не следует полагаться на это. Если вы хотите проверить равенство, используйте оператор ==. Если вы действительно хотите проверить идентичность объекта, используйте is
--- и мне было бы трудно придумать случай, когда вам следует позаботиться об идентичности строкового объекта. К сожалению, из-за вышеупомянутого интернирования вы не можете рассчитывать на то, являются ли две строки как-то «намеренно» идентичными ссылками на объекты.
Ключевое слово 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