Как внедрено ключевым словом «IS» в Python?
-
24-10-2019 - |
Вопрос
... 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
Работает только тогда, когда строки пройдены. Если вы действительно не знаете, что делаете, и явно Интернизован Строки, которые вы должны никогда использовать is
на струнах.
is
тесты для личность, нет равенство. Анкет Это означает, что Python просто сравнивает адрес памяти, в котором находится объект. is
В основном отвечает на вопрос: «Есть ли у меня два имени для одного и того же объекта?» - Перегрузка, которая не имеет смысла.
Например, ("a" * 100) is ("a" * 100)
является ЛОЖЬ. Анкет Обычно Python записывает каждую строку в другое местоположение памяти, в основном случаи стажинг происходит для строковых литералов.
Другие советы
А is
Оператор эквивалентен сравнению id(x)
ценности. id
в настоящее время реализован для использования указателей в качестве сравнения. Так что вы не можете перегрузить is
сам, и afaik, вы не можете перегрузить id
либо.
Итак, вы не можете. Необычный в Python, но там.
Питон is
Ключевые тесты объекта идентичность объекта. Вы не должны использовать его для тестирования на равенство строки. Может показаться, что это часто работает, потому что реализации 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
Если вы не боитесь возиться с Bytecode, вы можете перехватить и исправить COMPARE_OP
с 8 ("is")
Аргумент, чтобы вызвать функцию крючка на сравниваемых объектах. смотреть на 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» сравнивает идентичность объекта, тогда как == сравнивает значения.
Пример:
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
Вы не можете перегрузить is
оператор. То, что вы хотите перегрузить, - это ==
оператор. Это можно сделать, определив __eq__
Метод в классе.
Вы используете сравнение идентификаций. == Вероятно, вы хотите. Исключение - когда вы хотите проверить, являются ли один элемент, а другой - одинаковым объектом и в той же позиции памяти. В ваших примерах элемент не совпадает, поскольку один из них имеет другой тип (my_string), чем другой (строка). Кроме того, нет такой вещи, как что -то.__is__
В Python (если, конечно, вы сами не поместите это). Если бы это было, сравнивая объекты с является Не будет надежным, чтобы просто сравнить местоположения памяти.
Когда я впервые столкнулся является Ключевое слово, это меня тоже запутало. Я бы подумал, что является и == ничем не отличались. Они произвели тот же выходной от интерпретатора на многих объектах. Этот тип предположения на самом деле именно то, что является... для. Это эквивалент Python: «Эй, не пускайте эти два объекта. Они разные». Это, по сути, то, что [кем бы это ни было, это было, что это выпрямило]. Сформулировано по -другому, но одна точка == Другой момент.
Для некоторых полезных примеров и некоторого текста, чтобы помочь с иногда запутанным посещением Документ от почтового хоста Python.org написано "Дэнни Ю"
или, если это автономный, используйте Незаправленная пастебин Я сделал из его тела.
В случае, если они, примерно в 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
###
Ошибки утверждения могут легко возникнуть с является Ключевое слово при сравнении объектов. Например, объекты а а также беременный может иметь одинаковое значение и поделиться тем же адресом памяти. Поэтому выполнение
>>> a == b
собирается оценить
True
Но если
>>> a is b
оценивает
False
Вы, вероятно, должны проверить
>>> type(a)
а также
>>> type(b)
Это может быть иначе и причиной неудачи.