Подробнее о Python | Python: Настройка окружения
Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером
Чтобы глубже погрузиться в настройку окружения Python, нам нужно вспомнить теоретические основы этого языка. Они помогут глубже разобраться в окружении и работе с ним.
Язык программирования
Что такое язык программирования? За этим понятием скрываются две связанных, но независимых темы.
С одной стороны, языком программирования называют синтаксические и семантические правила, по которым записывается и работает исходный код.
В отличие от естественных языков, эти правила достаточно строги. Любая мельчайшая ошибка приведет к тому, что код либо не запустится, либо будет работать некорректно.
Например, в Python нельзя написать my name = 5
с пробелом в имени переменной. Эти правила существуют не только в книгах, но и в головах конкретных программистов и разработчиков языка.
Часто весь свод правил существует в виде отдельного специального документа и называется спецификацией.
С другой стороны, языком программирования называют программу, которая запускает и компилирует наш код. Обычно ее называют средой выполнения.
Среда выполнения — это конкретное воплощение спецификации, поэтому ее иногда называют реализацией.
У конкретного языка может существовать несколько реализаций, в том числе эталонная реализация, на которую равняются все остальные. Различные реализации могут разрабатываться разными людьми и компаниями.
У Python нет выделенной спецификации, но есть эталонная реализация. Она называется CPython — это интерпретатор Python, реализованный на языке C. Если вы слышите разговоры про Python, то скорее всего имеется в виду именно эталонная реализация CPython.
Прочие варианты обычно имеют свои названия. Например, реализация языка для запуска программ на платформе .NET называется IronPython.
Python
Python — интерпретируемый язык программирования с сильной динамической типизацией. Разберем эти слова по отдельности.
Интерпретируемый язык программирования
Существуют языки программирования, в которых есть стадия компиляции в машинный код. Например, компиляция есть у языков C, Rust, Go. Это компилируемые языки.
Python работает по-другому. Программа исполняется интерпретатором шаг за шагом, а не запускается напрямую на процессоре компьютера. Поэтому для запуска программы на Python всегда нужна среда исполнения (интерпретатор). Только она может выполнять Python-программы.
Строго говоря, и у Python есть фаза компиляции, но при этом внешне он ведет себя именно как интерпретируемый язык программирования:
- Вы запускаете программу
- Интерпретатор открывает файлы программы и загружает из них исходный код
- Затем интерпретатор преобразует исходный код в байткод, проверяет ошибки синтаксиса и начинает исполнять по шагам
Динамическая типизация
Есть языки, в которых интерпретатор производит проверку типов, доступности функций и переменных во время выполнения кода.
В статически типизированных языках подобные ошибки отслеживаются раньше — на этапе анализа исходного текста без запуска кода на выполнение. Слово «статический» как раз означает, что программа не выполняется.
Обычно статическими проверками занимаются компиляторы, но существуют и специальные инструменты — статические анализаторы кода. Для некоторых языков с динамической типизацией такие анализаторы тоже существуют, но отслеживают значительно меньшее число ошибок.
Сильная типизация
язык программирования, созданный сообществом / Хабр
Это перевод доклада с голландского TED Talks, прочитанного Гвидо Ван Россумом, «великодушным пожизненным диктатором» языка программирования Python. Много автобиографии и немного про значение языков программирования и основную идею Python.
Позвольте представиться — я нерд, гик. И я постоянно медлю. Я закончил университет в 26, мне было 45, когда я женился, сейчас мне 60, и у меня четырнадцатилетний сын. Может, мне просто трудно даются решения: я прожил в США больше 20 лет, но всё ещё имею вид на жительство.
Я не Стив Джобс или Марк Цукерберг. Но в возрасте 35 лет я создал язык программирования, который нашёл своих последователей. То, что произошло после этого, невероятно. Но об этом позже.
В 10 лет родители подарили мне образовательный набор электроники, выпущенный Philips, и он был крут. По началу я просто следовал инструкциям, и всё работало. Позже я начал пробовать создавать собственные цепи: в наборе было целых три транзистора!
Я взял одну из моих моделей, мигающую лампочку, в школу. Но в моём пятом классе всем было всё равно, никто не осознал важности этой конструкции. Я думаю, тогда я впервые понял, что я гик: до этого я просто был умным тихоней.
В старшей школе я всё больше становился нердом — я тусовался с несколькими детьми, также интересовавшимися электроникой, и на уроках физики мы сидели сзади и обсуждали штрих Шеффера, пока все остальные разбирались с законом Ома.
К счастью, наш учитель физики заметил нас, и занял созданием цифрового таймера, который он использовал для объяснения законов гравитации остальному классу. Это был замечательный проект, который показал, что наши умения полезны. Остальные дети всё ещё считали нас странными: в семидесятых многие были бунтарями или курителями «дудки»; остальные уже готовились к успешной карьере докторов, или адвокатов, или менеджеров. Но они меня не трогали, я не трогал их тоже, и в итоге выпустился одним из лучших учеников.
После старшей школы я поступил в Амстердамский университет: он был близко от дома, и для подростка, выросшего в Нидерландах в семидесятых, Амстердам был единственным крутым городом (да, студенческие протесты 1968-го слегка меня зацепили). К большому удивлению моего школьного учителя физики я выбрал математику, но, оглядываясь назад, я не думаю, что была какая-нибудь разница.
В подвале научного корпуса был мейнфрейм, и я полюбил его с первого взгляда. Карточные перфораторы! Построчные принтеры! Пакетная обработка! Я быстро научился программировать на языках вроде Алгола, Фортрана и Паскаля. Сейчас эти названия почти забыты, но они имели большое влияние тогда. Вскоре я снова сидел в конце аудитории, игнорируя лекции и исправляя свои компьютерные программы. А почему?
В подвале, вокруг мейнфрейма, творилось нечто невообразимое. Там была сплоченная группа студентов и сотрудников со схожими интересами, которая обменивалась трюками и секретами. Мы делились процедурами и программами. Мы объединялись в альянсы против обслуживающего персонала мейнфрейма, особенно в играх в кошки-мышки за свободное дисковое пространство (свободное место на диске было действительно священным тогда).
Но главный урок, который я усвоил, был про обмен знаниями: хотя большинство трюков, которые я выучил тогда, умерли вместе с эрой больших компьютеров, идея о ПО, которым необходимо делиться, жива как никогда. Сейчас мы называем это “open source”, и это целое движение. Отметьте это!
Группа разработчиков ОС мейнфрейма набирала нескольких студентов. Они разместили вакансию, я откликнулся, и получил работу. Это было событие, изменившее жизнь! Внезапно у меня появился полный доступ к мейнфрейму (без войн за свободное место или терминалы) и доступ к исходникам его операционной системы, а так же куча коллег, которые объяснили мне, как всё это работает.
У меня была работа мечты: программировать целый день, с настоящими заказчиками — другими программистами и пользователями машины. Моя учёба застопорилась, и я почти бросил колледж, но меня вытянули мой менеджер и профессор, который не отказался от меня. Они подтолкнули меня к завершению нескольких курсов, и в конце концов, с большим опозданием, я стал выпускником.
Я немедленно перешёл на новую работу мечты, которая была закрыта для меня без диплома. Я никогда не терял интерес к языкам программирования, и в целях изучения вступил в команду, разрабатывавшую новый язык программирования — такое не каждый день увидишь. Дизайнеры надеялись, что их язык захватит мир и заменит Basic.
Были восьмидесятые, и Бейсик был выбором для нового поколения программистов-любителей, писавших под микрокомпьютеры вроде Apple II и Commodore 64. Наша команда считала Бейсик вредителем, от которого следует избавиться. Наш новый язык, ABC, должен был “искоренить Basic” — такой у нас был девиз.
Но к сожалению, с маркетингом (или сроками) у нас всё было не очень хорошо, и после четырёх лет ABC был заброшен. С тех пор я убил много часов, пытаясь понять почему проект провалился, хотя и был в нужном месте в нужное время. За исключением того, что язык был слегка избыточным, я пришёл к выводу, что ABC умер просто потому, что тогда не было интернета. Не было обратной связи между создателями языка и его пользователями. Дизайн ABC изначально был дорогой с односторонним движением.
Пять лет спустя, когда я копался в остатках ABC в поисках идей для моего собственного языка программирования, я решил устранить недостаток обратной связи. Моим девизом стал “выпускай рано, выпускай часто” (как у чикагских демократов — “голосуй рано, голосуй часто”). И интернет, маленький и медленный в 1990, позволил это сделать.
Если посмотреть на 30 лет назад, то интернет и Open Source (a. k.a Free Software) действительно многое поменяли. Ну и конечно же закон Мура, согласно которому компьютеры становились всё быстрее из года в год. В совокупности всё это изменило взаимодействие между создателями и пользователями компьютерного ПО. Я считаю, что эти события (и то, как я их использовал) привнесли больше в успех “моего” языка программирования, чем мой опыт и навыки программирования.
Также не повредило то, что я назвал свой язык Python — немного невольного маркетингового гения с моей стороны. Я назвал его так в честь комедийного шоу Monty Python’s Flying Circus, и в 1990-м это не повлекло никаких последствий. Сегодня, я уверен, куча фирм по исследованию брендов были бы счастливы выписать большой штраф за то, какие сложные ассоциации такое название может вызывать в подсознании клиента. Но я был просто легкомысленным.
Я обещал не загружать вас технической речью на тему достоинств различных языков программирования. Но я хочу сказать несколько вещей про то, что языки программирования значат для людей, которые их используют — для программистов. Если попросить программиста объяснить простому человеку что такое язык программирования, он ответит, что это способ заставить компьютер делать то, что тебе нужно. Но если это всё, почему программисты так яро обсуждают языки между собой?
В реальности, языки программирования определяют то, как программисты выражают свои идеи и обмениваются ими. Причина: компьютер обработает всё, что угодно, а вот программисты работают с другими программистами, и плохо переданная идея может стать причиной дорогостоящего провала. Фактически, идеи выраженные в языке программирования часто достигают конечных пользователей программы.
Подумайте о невероятном успехе компаний вроде Google или Facebook. В их корне лежат идеи — идеи насчёт того, что компьютеры могут сделать для людей. Чтобы быть эффективной, идея должна быть выражена в компьютерной программе с использованием языка программирования. И язык, который позволит лучше всего выразить идею, даст команде ключевое преимущество, потому что даёт членам команды — людям! — ясность идеи. Идеи в недрах Google и Facebook настолько различны, насколько возможно, и на самом деле избранные этими компаниями языки программирования находятся на противоположных концах спектра дизайна языков программирования.
True story: первая версия Google была написана на Python. Причина: Python был правильным языком для выражения оригинальных идей Ларри Пейджа и Сергея Брина про индексацию веба и организацию результатов поиска. И они смогли реализовать свои идеи на компьютере!
Итак, в 1990-м, задолго до Google и Facebook, я создал собственный язык программирования, и назвал его Python. Но в чём его идея? Почему он настолько успешен? Чем он отличается от других языков программирования? (Почему вы все на меня так смотрите? 🙂
У меня много ответов, некоторые технические, некоторые из моего многолетнего опыта и навыков, некоторые просто вроде “был в нужное время в нужном месте”. Но я верю что главная идея — это то, что язык разрабатывался в интернете, изначально открыто, сообществом волонтёров (но не любителей!), которые страстно привязаны к нему.
И это как раз то, о чём раньше была речь в части про подвал научного корпуса.
Сюрприз: как и у любой хорошей мотивационной речи, цель этого доклада — это радость!
Я больше всего счастлив когда чувствую себя частью сообщества. Мне повезло, что я могу чувствовать это и в ежедневной работе (я ведущий инженер в Dropbox). И если я не могу испытывать это чувство, я перестану чувствовать себя живым. Это чувство заразно, и поэтому члены нашего сообщества есть во всём мире.
Сообщество пользователей Python — это миллионы людей, которые сознательно используют его, и им это нравится. Многие активно участвуют в организации конференций — PyCon — в таких удалённых местах как Намибия, Ирак и даже Огайо!
Моя любимая история: год назад я провёл 20 минут на видеоконференции с классом, полным преподавателей и сотрудников Babylon University в Ираке, отвечая на их вопросы по Python. Благодаря усилиям смелой женщины, которая огранизовала такое мероприятие даже в охваченной войной стране, студенты в Вавилонском унивеситете в настоящее время изучают введение в программирование с использованием Python. В своих самых смелых мечтах я никогда не ожидал, что буду влиять на жизни столь далёкие и столь сильно отличающиеся от моей.
И на этой ноте я вас покидаю: язык программирования, созданный сообществом, способствует счастью своих пользователей. В следующем году я, возможно, поеду на кубинский PyCon!
Сравнение объектов в Python — Real Python
Смотреть сейчас Это руководство содержит соответствующий видеокурс, созданный командой Real Python. Посмотрите его вместе с письменным учебным пособием, чтобы углубить свое понимание: Правильное сравнение объектов Python: «is» vs «==»
Существует тонкая разница между оператором идентификации Python ( is
) и оператором равенства ( ==
). Ваш код может работать нормально, если вы используете оператор Python is
для сравнения чисел, пока он вдруг не перестанет работать. Возможно, вы где-то слышали, что Python 9Оператор 0008 is быстрее, чем оператор ==
, или вам может показаться, что он выглядит более Pythonic. Однако важно помнить, что эти операторы ведут себя по-разному.
Оператор ==
сравнивает значение или равенство двух объектов, тогда как оператор Python is
проверяет, указывают ли две переменные на один и тот же объект в памяти. В подавляющем большинстве случаев это означает, что вы должны использовать операторы равенства
и !=
, за исключением случаев, когда вы сравниваете с None
.
Из этого руководства вы узнаете:
- В чем разница между равенством объектов и идентичностью
- Когда использовать операторы равенства и идентичности для сравнения объектов
- Что эти оператора Python делают под капотом
- Почему использование
— это
, а— это не
для сравнения значений, что приводит к неожиданному поведению - Как написать пользовательский
__eq__()
метод класса для определения поведения оператора равенства
Пит-стоп Python: Это руководство представляет собой быстрый и практичный способ найти нужную информацию, так что вы вернетесь к своему проекту в кратчайшие сроки!
Бесплатный бонус: Нажмите здесь, чтобы получить шпаргалку по Python и изучить основы Python 3, такие как работа с типами данных, словарями, списками и функциями Python.
Сравнение удостоверений с Python есть и не является операторами
Python — это
, а — это не
, операторы сравнивают тождество двух объектов. В CPython это их адрес памяти. Все в Python является объектом, и каждый объект хранится в определенном месте памяти. Операторы Python — это
, а — это не
, проверяющие, ссылаются ли две переменные на один и тот же объект в памяти.
Примечание: Имейте в виду, что объекты с одинаковым значением обычно хранятся по разным адресам памяти.
Вы можете использовать id()
для проверки подлинности объекта:
>>> справка(id) Справка по встроенному идентификатору функции во встроенных модулях: идентификатор (объект, /) Вернуть идентификатор объекта. Это гарантированно будет уникальным среди одновременно существующих объектов. (CPython использует адрес памяти объекта. ) >>> идентификатор (id) 2570892442576
В последней строке указан адрес памяти, где хранится сама встроенная функция id
.
В некоторых распространенных случаях объекты с одинаковым значением по умолчанию будут иметь одинаковый идентификатор. Например, числа от -5 до 256 — это , интернированное в CPython. Каждое число хранится в единственном и фиксированном месте в памяти, что экономит память для часто используемых целых чисел.
Вы можете использовать sys.intern()
для интернирования строк для повышения производительности. Эта функция позволяет сравнивать их адреса памяти, а не сравнивать строки посимвольно:
>>>
>>> из sys import стажер >>> a = 'привет, мир' >>> b = 'привет, мир' >>> а есть б ЛОЖЬ >>> идентификатор (а) 1603648396784 >>> идентификатор (б) 1603648426160 >>> а = стажер(а) >>> б = стажер(б) >>> а есть б Истинный >>> идентификатор (а) 1603648396784 >>> идентификатор (б) 1603648396784
Переменные a
и b
изначально указывают на два разных объекта в памяти, о чем свидетельствуют их разные идентификаторы. Когда вы стажируете их, вы гарантируете, что a
и b
указывают на один и тот же объект в памяти. Любая новая строка со значением 'hello world'
теперь будет создаваться в новой ячейке памяти, но когда вы интернируете эту новую строку, вы убедитесь, что она указывает на тот же адрес памяти, что и первый
. что вы интернировали.
Примечание: Несмотря на то, что адрес памяти объекта уникален в любой момент времени, он различается между запусками одного и того же кода и зависит от версии CPython и компьютера, на котором он работает.
Другими интернированными объектами по умолчанию являются None
, True
, False
и простые строки. Имейте в виду, что в большинстве случаев разные объекты с одинаковым значением будут храниться по разным адресам памяти. Это означает, что вы не должны использовать оператор Python is
для сравнения значений.
Удаление рекламы
Когда интернированы только некоторые целые числа
За кулисами Python интернирует объекты с часто используемыми значениями (например, целыми числами от -5 до 256) для экономии памяти. Следующий фрагмент кода показывает, что только некоторые целые числа имеют фиксированный адрес памяти:
>>>
>>> а = 256 >>> б = 256 >>> а есть б Истинный >>> идентификатор (а) 1638894624 >>> идентификатор (б) 1638894624 >>> а = 257 >>> б = 257 >>> а есть б ЛОЖЬ >>> идентификатор (а) 2570926051952 >>> идентификатор (б) 2570926051984
Первоначально a
и b
указывают на один и тот же интернированный объект в памяти, но когда их значения выходят за пределы диапазона обычных целых чисел (в диапазоне от -5 до 256), они сохраняются по разным адресам памяти.
Когда несколько переменных указывают на один и тот же объект
Когда вы используете оператор присваивания ( =
), чтобы сделать одну переменную равной другой, вы заставляете эти переменные указывать на один и тот же объект в памяти.
>>>
>>> а = [1, 2, 3] >>> б = а >>> а [1, 2, 3] >>> б [1, 2, 3] >>> а.добавить(4) >>> а [1, 2, 3, 4] >>> б [1, 2, 3, 4] >>> идентификатор (а) 2570926056520 >>> идентификатор (б) 2570926056520
Что только что произошло? Вы добавляете новый элемент в a
, но теперь b
содержит и этот элемент! Что ж, в строке, где b = a
, вы устанавливаете b
так, чтобы она указывала на тот же адрес памяти, что и a
, так что теперь обе переменные ссылаются на один и тот же объект.
Если вы определяете эти списки независимо друг от друга, то они хранятся по разным адресам памяти и ведут себя независимо:
>>>
>>> а = [1, 2, 3] >>> б = [1, 2, 3] >>> а есть б ЛОЖЬ > >> идентификатор (а) 2356388925576 >>> идентификатор (б) 2356388952648
Поскольку a
и b
теперь относятся к разным объектам в памяти, изменение одного не влияет на другой.
Сравнение равенства с операторами Python == и !=
Напомним, что объекты с одинаковым значением часто хранятся по отдельным адресам памяти . Используйте операторы равенства ==
и !=
, если вы хотите проверить, имеют ли два объекта одинаковое значение, независимо от того, где они хранятся в памяти. В подавляющем большинстве случаев это то, что вы хотите сделать.
Когда копия объекта равна, но не идентична
В приведенном ниже примере вы устанавливаете b
как копию a
(который является изменяемым объектом, таким как список или словарь). Обе переменные будут иметь одинаковое значение, но каждая будет храниться по разным адресам памяти:
>>>
>>> а = [1, 2, 3] >>> b = a.copy() >>> а [1, 2, 3] >>> б [1, 2, 3] >>> а == б Истинный >>> а есть б ЛОЖЬ >>> идентификатор (а) 2570926058312 >>> идентификатор (б) 2570926057736
a
и b
теперь хранятся по разным адресам памяти, поэтому a is b
больше не будет возвращать True
. Однако a == b
возвращает True
, поскольку оба объекта имеют одинаковое значение.
Как работает сравнение по равенству
Магия оператора равенства ==
происходит в методе класса __eq__()
объекта слева от знака ==
.
Примечание: Это так, если только объект справа не является подклассом объекта слева. Для получения дополнительной информации проверьте официальную документацию.
Это магический метод класса, который вызывается всякий раз, когда экземпляр этого класса сравнивается с другим объектом. Если этот способ не реализован, то ==
по умолчанию сравнивает адреса памяти двух объектов.
В качестве упражнения создайте класс SillyString
, который наследуется от str
, и реализуйте __eq__()
, чтобы сравнить, совпадает ли длина этой строки с длиной другого объекта:
класс SillyString(str): # Этот метод вызывается при использовании == на объекте def __eq__(я, другой): print(f'сравнение {себя} с {другим}') # Возвращаем True, если self и other имеют одинаковую длину вернуть len(я) == len(другой)
Теперь SillyString 'hello world'
должен быть равен строке 'world hello'
и даже любому другому объекту такой же длины:
>>>
>>> # Сравнить две строки >>> 'привет, мир' == 'привет, мир' ЛОЖЬ >>> # Сравните строку с SillyString >>> 'привет, мир' == SillyString('привет, мир') сравнивая привет мир с привет мир Истинный >>> # Сравните SillyString со списком >>> SillyString('привет мир') == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] сравнение hello world с [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] Истинный
Это, конечно, глупое поведение для объекта, который иначе ведет себя как строка, но он иллюстрирует, что происходит, когда вы сравниваете два объекта, используя ==
. Оператор !=
дает ответ, обратный этому, если не реализован конкретный метод класса __ne__()
.
Приведенный выше пример также ясно показывает, почему рекомендуется использовать Python is 9.Оператор 0009 для сравнения с
None
вместо оператора ==
. Он не только быстрее, поскольку сравнивает адреса памяти, но и безопаснее, поскольку не зависит от логики каких-либо методов класса __eq__()
.
Удаление рекламы
Сравнение операторов сравнения Python
Как правило, вы всегда должны использовать операторы равенства ==
и !=
, за исключением случаев, когда вы сравниваете с Нет
:
Используйте операторы Python
==
и!=
для сравнения равенства объектов . Здесь вы обычно сравниваете ценность двух объектов. Это то, что вам нужно, если вы хотите сравнить, имеют ли два объекта одинаковое содержимое, и вам все равно, где они хранятся в памяти.Используйте операторы Python
is
иnot
, когда вы хотите сравнить идентификатор объекта . Здесь вы сравниваете, указывают ли две переменные на один и тот же объект в памяти. Основной вариант использования этих операторов — когда вы сравниваете сНет
. Сравнивать сNone
по адресу памяти быстрее и безопаснее, чем с помощью методов класса.
Переменные с одинаковыми значениями часто хранятся по разным адресам памяти. Это означает, что вы должны использовать ==
и !=
для сравнения их значений и использовать операторы Python is
и is not
только тогда, когда вы хотите проверить, указывают ли две переменные на один и тот же адрес памяти.
Вывод
Из этого руководства вы узнали, что ==
и !=
сравнивают значение двух объектов , тогда как Python — это
, а не
. Операторы сравнивают, относятся ли две переменные к одному и тому же объекту. в памяти . Если вы будете помнить об этом различии, вы сможете предотвратить неожиданное поведение в своем коде.
Если вы хотите узнать больше об удивительном мире объектов, интернированных и Python — это оператор
, а затем посмотрите, почему вы почти никогда не должны использовать «is» в Python. Вы также можете посмотреть, как вы можете использовать sys.intern()
для оптимизации использования памяти и времени сравнения для строк, хотя есть вероятность, что Python уже автоматически обрабатывает это за вас за кулисами.
Теперь, когда вы узнали, что делают под капотом операторы равенства и идентичности , вы можете попробовать написать свои собственные методы класса __eq__()
, которые определяют, как экземпляры этого класса сравниваются при использовании .0008 == оператор. Идите и примените свои новые знания об этих операторах сравнения Python!
Смотреть сейчас Это руководство содержит связанный с ним видеокурс, созданный командой Real Python. Посмотрите его вместе с письменным учебным пособием, чтобы углубить свое понимание: Правильное сравнение объектов Python: «is» и «==»
python. Есть ли разница между «==» и «is»?
Есть ли разница между
==
иэто
на питоне?
Да, у них есть очень важное отличие.
==
: проверка на равенство — семантика такова, что эквивалентные объекты (которые не обязательно являются одним и тем же объектом) будут проверяться как равные. Как сказано в документации:
Операторы <, >, ==, >=, <= и != сравнивают значения двух объектов.
- это
: проверка на идентичность — семантика такова, что объект (как хранится в памяти) это объект. Опять же в документации написано:
Операторы
— это
, а— это не
проверка идентичности объекта:x — это y
верно тогда и только тогда, когдаx
иy
являются одним и тем же объектом. Идентификация объекта определяется с помощью функции id() .х не у
дает обратное значение истины.
Таким образом, проверка на идентичность аналогична проверке на равенство идентификаторов объектов. то есть
а есть б
совпадает с:
id(a) == id(b)
, где id
— это встроенная функция, которая возвращает целое число, которое «гарантированно будет уникальным среди одновременно существующих объектов» (см. help(id)
), и где a
и b
— любые произвольные объекты.
Другие указания по использованию
Вы должны использовать эти сравнения для их семантики. Используйте =
для проверки подлинности и ==
для проверки равенства.
Обычно мы используем —
для проверки личности. Обычно это полезно, когда мы проверяем наличие объекта, который должен существовать в памяти только один раз, в документации он называется «синглтон».
Варианты использования для is
включают:
-
Нет
- значений перечисления (при использовании перечислений из модуля перечисления)
- обычно модули
- обычно объекты класса, полученные из определений классов
- обычно функционируют объекты, являющиеся результатом определений функций
- все остальное, что должно существовать в памяти только один раз (как правило, все синглтоны)
- конкретный объект, который вы хотите по идентификатору
Обычные варианты использования для ==
включают:
- числа, включая целые числа
- строк
- списков
- комплектов
- словарей
- настраиваемых изменяемых объектов
- других встроенных неизменяемых объектов, в большинстве случаев
Общий вариант использования, опять же, для ==
, объект, который вы хотите, может не быть тем же объектом , вместо этого он может быть эквивалентом один
PEP 8 направлений
PEP 8, официальное руководство по стилю Python для стандартной библиотеки также упоминает два варианты использования для :
:
Сравнения с синглтонами, такими как
Нет
всегда следует делать сравно
или— это не
, а не операторы равенства.Также остерегайтесь писать
, если x
, когда вы действительно имеете в виду, если x не равно None
— например при проверке того, является ли переменная или аргумент значением по умолчаниюНет
было установлено какое-то другое значение. Другое значение может иметь тип (например, как контейнер), что может быть ложным в логическом контексте!
Вывод равенства из тождества
Если равно
истинно, равенство может быть обычно выведено — логически, если объект является самим собой, то он должен проверяться как эквивалентный самому себе.
В большинстве случаев эта логика верна, но она зависит от реализации специального метода __eq__
. Как говорится в документах,
Поведение по умолчанию для сравнения на равенство (
==
и!=
) основано на идентичность объектов. Следовательно, сравнение на равенство экземпляров с одним и тем же тождеством приводит к равенству, а сравнение равенства экземпляры с разными идентификаторами приводят к неравенству. А мотивация такого поведения по умолчанию — желание, чтобы все объекты должен быть рефлексивным (т. е. x равно y подразумевает x == y).
и в интересах единообразия рекомендует:
Сравнение равенства должно быть рефлексивным. Другими словами, идентичные объекты должны сравниваться равными:
х есть у
подразумеваетх == у
Мы видим, что это поведение по умолчанию для пользовательских объектов:
>>> class Object(object): pass >>> объект = Объект() >>> obj2 = Объект() >>> obj == obj, obj есть obj (Правда правда) >>> obj == obj2, obj есть obj2 (Ложь, Ложь)
Противоположное также обычно верно — если что-то проверяется как неравное, вы обычно можете сделать вывод, что это не один и тот же объект.
Поскольку тесты на равенство можно настраивать, этот вывод не всегда верен для всех типов.
Исключение
Заметным исключением является nan
— он всегда проверяется как не равный самому себе:
>>> nan = float('nan') >>> нан нан >>> нан есть нан Истинный >>> нан == нан # !!!!! ЛОЖЬ
Проверка на идентичность может быть намного быстрее, чем проверка на равенство (для чего может потребоваться рекурсивная проверка членов).
Но его нельзя заменить равенством, если вы можете найти более одного эквивалентного объекта.
Обратите внимание, что при сравнении списков и кортежей предполагается, что идентичные объекты (поскольку это быстрая проверка). Это может создать противоречия, если логика непоследовательна — как для nan
:
>>> [nan] == [nan] Истинный >>> (нан) == (нан) Истинный
Предостережение:
Вопрос заключается в попытке использовать вместо
для сравнения целых чисел. Не следует предполагать, что экземпляр целого числа — это тот же экземпляр, что и экземпляр, полученный по другой ссылке. Эта история объясняет, почему.
У комментатора был код, который полагался на тот факт, что маленькие целые числа (от -5 до 256 включительно) являются одиночками в Python, вместо проверки на равенство.
Ничего себе, это может привести к некоторым коварным ошибкам. У меня был некоторый код, который проверял, является ли a b, который работал так, как я хотел, потому что a и b обычно небольшие числа.