Оператор «is» не работает должным образом

Просто взгляните на этот код:

import re ti = "abcd" tq = "abcdef" check_abcd = re.compile('^abcd') print id(check_abcd.search(ti)) print id(check_abcd.search(tq)) print check_abcd.search(ti) print check_abcd.search(tq) if check_abcd.search(ti) is check_abcd.search(tq): print "Matching" else: print "not matching" 

Вывод:

 41696976 41696976 <_sre.SRE_Match object at 0x00000000027C3ED0> <_sre.SRE_Match object at 0x00000000027C3ED0> not matching 

Определение:

 `is` is identity testing, == is equality testing. is will return True if two variables point to the same object 

1) Теперь почему это не возвращает True когда id, а также ссылка на объект такая же.

2) Когда is заменяется на == он все равно возвращает false Это ожидаемое поведение при сравнении объектов с использованием == .

  • Почему «if foo:» следует за веткой, даже если функция foo возвращает False?
  • Имитировать интерактивную сессию python
  • Python - Дескриптор 'split' требует объекта 'str', но получил 'unicode'
  • Сервер AppEngine не может импортировать модуль атома
  • Как легко установить модули python и иждивенцев?
  • прерывать / прерывать time.sleep () в python
  • subprocess.call, требующий разделения всех параметров запятыми
  • webapp2 + jinja2: Как я могу получить uri_for (), работающий в jinja2-views
  • 3 Solutions collect form web for “Оператор «is» не работает должным образом”

    Вы никогда не назначали возвращаемые значения, поэтому после печати значения id() возвращаемого значения check_abcd.search() Python отбрасывает объект возвращаемого значения, поскольку больше ничего не ссылается на него. Время жизни объектов CPython напрямую зависит от количества ссылок на них; как только этот счетчик ссылок упадет до 0, объект будет удален из памяти.

    Выбранные ячейки памяти могут быть повторно использованы, поэтому вам захочется увидеть одинаковые значения в вызовах id() . См. Документацию id() :

    Верните «идентификатор» объекта. Это целое число (или длинное целое число), которое гарантировано будет уникальным и постоянным для этого объекта в течение его жизни. Два объекта с неперекрывающимся временем жизни могут иметь одинаковое значение id() .

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

    Назначьте возвращаемые значения, если вы хотите убедиться, что значения id() не используются повторно:

     >>> import re >>> ti = "abcd" >>> tq = "abcdef" >>> check_abcd = re.compile('^abcd') >>> ti_search = check_abcd.search(ti) >>> tq_search = check_abcd.search(tq) >>> id(ti_search), id(tq_search) (4378421952, 4378422056) >>> ti_search, tq_search (<_sre.SRE_Match object at 0x104f96ac0>, <_sre.SRE_Match object at 0x104f96b28>) >>> ti_search is tq_search False 

    check_abcd.search() возвращаемые значения check_abcd.search() (регулярное выражение MatchObject s), создается дополнительная ссылка, и Python не может повторно использовать ячейку памяти.

    Если вы это сделаете: print id(check_abcd.search(ti)) в строке и не print id(check_abcd.search(ti)) возвращаемое значение search любом месте, счетчик ссылок будет равен нулю, и он будет уничтожен. Вызов в строке ниже создает другой объект, который находится в том же адресе памяти (который используется CPython как идентификатор объекта), но это не тот же объект.

    Когда вы используете оператор is , предыдущий объект все еще должен существовать, чтобы происходило сравнение, и его адрес будет другим.

    Просто поместите результаты вызовов check_abcd.search в переменную перед печатью своего идентификатора (и используйте разные переменные), и вы сможете увидеть, что на самом деле происходит.

    Более того: продолжение в этих строках может быть поучительным, если вы хотите узнать о поведении «is» и идентификаторов объектов, но если вы хотите сравнить строки и возвращаемые значения, просто используйте оператор == , никогда не is : последующие вызовы функций , даже если возвращение одного и того же значения не должно возвращать один и тот же объект – сравнение рекомендуется только при сравнении с «Нет» (которое реализуется как одноэлементное)

    Martjin дал вам правильный ответ, но для дальнейшего уточнения здесь представлена ​​аннотированная версия того, что происходит в вашем коде:

     # this line creates returns a value from .search(), # prints the id, then DISCARDS the value as you have not # created a reference using a variable. print id(check_abcd.search(ti)) # this line creates a new, distinct returned value from .search() # COINCIDENTALLY reusing the memory address and id of the last one. print id(check_abcd.search(tq)) # Same, a NEW value having (by coincidence) the same id print check_abcd.search(ti) # Same again print check_abcd.search(tq) # Here, Python is creating two distinct return values. # The first object cannot be released and the id reused # because both values must be held until the conditional statement has # been completely evaluated. Therefore, while the FIRST value will # probably reuse the same id, the second one will have a different id. if check_abcd.search(ti) is check_abcd.search(tq): print "Matching" else: print "not matching" 
    Python - лучший язык программирования в мире.