Python Немає порівняння: чи слід використовувати "є" або ==?


213

Мій редактор попереджає мене, коли я порівнюю my_var == None, але жодного попередження при використанні my_var is None.

Я зробив тест в оболонці Python і визначив, що обидва є коректним синтаксисом, але, здається, мій редактор говорить, що my_var is Noneкращий.

Це так, і якщо так, то чому?


7
PEP 8 десь говорить, що вам слід порівнювати з однотонними, використовуючи is- python.org/dev/peps/pep-0008/#programming-recommendations
Нестабільність

2
Цей плакат говорить про Python 3, а моє запитання про Python 2.x. Я не впевнений, чи це досить велика різниця, щоб вимагати як залишилися, але я змінив питання, щоб включити це на всякий випадок.
Clay Wardell

2
Я не думаю, що це питання насправді повторюється. Інше було про == vs взагалі, це про Ніхто, зокрема.
IJ Kennedy

Відповіді:


254

Підсумок:

Використовуйте, isколи ви хочете перевірити ідентичність об'єкта (наприклад, перевірити, чи varє None). Використовуйте, ==коли ви хочете перевірити рівність (наприклад, varдорівнює 3?).

Пояснення:

Ви можете мати власні класи, куди my_var == NoneповернетесьTrue

наприклад:

class Negator(object):
    def __eq__(self,other):
        return not other

thing = Negator()
print thing == None    #True
print thing is None    #False

isперевірки ідентичності об'єкта . Є лише 1 об’єкт None, тож коли ви це робите my_var is None, ви перевіряєте, чи є вони насправді одним і тим же об’єктом (а не лише еквівалентними об'єктами)

Іншими словами, ==це перевірка на еквівалентність (яка визначається від об'єкта до об'єкта), тоді як isперевірка ідентичності об'єкта:

lst = [1,2,3]
lst == lst[:]  # This is True since the lists are "equivalent"
lst is lst[:]  # This is False since they're actually different objects

22
Коли is Noneвідрізняється від == None?
Блендер

11
@Blender У згаданому випадку. __eq__можна визначити будь-яким способом, але поведінку isне можна змінити так легко.
Лев Левицький

5
@LevLevitsky: Одним із прикладів використання Mython було "розширення протоколів, щоб будь-який оператор міг бути навіть перевантажений is". Після коментаря до списків він змінив це на "... навіть is(але тільки якщо ти божевільний)".
abarnert

1
+1, але було б ще краще, якби ця відповідь включала в себе посилання PEP 8, яке роблять інші (а також пояснення, чому рішення, яке стоїть за PEP 8, має сенс, яке воно вже робить).
abarnert

3
@abarnert - Я навіть не знав, що PEP 8 тут зробив рекомендацію. Справа в тому, що вони різні оператори, які роблять різні речі. Можуть бути випадки, коли object == Noneнасправді це правильна ідіома (хоча я не можу придумати жодної вершини голови). Вам просто потрібно знати, що ви робите.
mgilson

127

isяк правило, кращим є при порівнянні довільних об'єктів з одинаковими, Noneтому що це швидше і передбачуваніше. isзавжди порівнює за ідентичністю об'єкта, тоді як те, що ==буде робити, залежить від точного типу операндів і навіть від їх упорядкування.

Цю рекомендацію підтримує PEP 8 , де прямо вказано, що "порівняння з одинаковими клавішами, як None, завжди слід проводити з операторами рівності isабо is not, ніколи,".


6
Дякуємо за повідомлення про це; прийнята відповідь дає деякі цікаві моменти, але ваша відповідає на питання набагато прямо.
Люк Девіс

Здається дивно покладатися на те, що по суті є деталізацією реалізації. Чому я повинен дбати, скільки існує примірників NoneType?
BallpointBen

@BallpointBen Оскільки це не детальна інформація про реалізацію - Noneпід глобальною константою є лише один об'єкт None. Якщо що-небудь, NoneTypeце деталь реалізації, тому що Noneсинглтон повинен мати певний тип. (Той факт, що ви не можете створити екземпляри цього типу, є хорошим свідченням того, що його один екземпляр призначений бути
однотонним

@BallpointBen Я думаю, що ключовим моментом є те, що Python має сильну концепцію ідентичності об'єкта. Якщо ви хочете перевірити , порівнює чи об'єкт , рівний To None, всі засоби використовувати obj == None. Якщо ви хочете перевірити , є чи об'єкт є None використовувати obj is None. Суть рекомендації PEP 8 (і в цій відповіді) полягає в тому, що більшість людей хочуть останнього, коли вони хочуть перевірити наявність "None", а також, швидше і зрозуміліше.
користувач4815162342

Noneтакож відрізняється від кешованих об'єктів типу 0та інших малих цілих чисел, де кешування дійсно є деталлю реалізації. Різниця полягає в тому, що ціле число має внутрішнє значення, яке дає його властивості, і його можна обчислити. З іншого боку, Noneнемає жодної держави, важлива лише її особистість і робить її особливою.
користувач4815162342

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.