Python! = операция по сравнению с “не”

В комментарии к этому вопросу я видел оператор, который рекомендовал использовать

result is not None

по сравнению с

result != None

Я задавался вопросом, что различие, и почему можно было бы быть рекомендован по другому?

222
задан Community 23 May 2017 в 02:18
поделиться

5 ответов

== является тестом на равенство. Он проверяет, являются ли правая и левая стороны равными объектами (в соответствии с их методами __eq__ или __cmp__)

is является тестом на идентичность. Он проверяет, являются ли правая и левая стороны одним и тем же объектом. Методы не выполняются, объекты не могут влиять на работу is.

Вы используете isis not) для синглетов, как None, где вас не волнуют объекты, которые могут притворяться None, или где вы хотите защитить от взлома при сравнении с None.

272
ответ дан 23 November 2019 в 04:01
поделиться

Для решения вопроса 2 Java может быть немного болевым в обработке чисел с плавающей запятой, но он стал намного лучше, чем версии 1.5 и 1.6. При переходе по пути Java убедитесь в наличии последней доступной версии.

Соответствующие вопросы достаточно хорошо объясняются в этой статье: http://www.ibm.com/developerworks/java/library/j-math2.html .

-121--3049980-

Я не думаю, что это может быть сделано без неконтролируемого кастинга где-то. Вам понадобится нечто подобное экзистенциальным типам Хаскелла , которых нет в Java.

Вместо этого клиент может выполнить бесконтрольный кастинг...

synchronized public static <V> FieldBinder<V>
getInstance(Class<V> klass, Class<FieldBinder<V>> binderKlass) {
    if(!instanceMap.containsKey(klass)) {
        instanceMap.put(klass, new FieldBinder<V>());
    }
    return binderKlass.cast(instanceMap.get(klass));
}

Если клиент передает метод Class < StartBinder < V > > методу getInstance () , можно избежать отсутствия флажка в getInstance () .

К сожалению, создавая Класс > сам требует незарегистрированного броска.

Class<FieldBinder<Integer>> binderKlass =
    (Class<FieldBinder<Integer>>) (Class<?>) FieldBinder.class;
BinderAssociator.getInstance(Integer.class, binderKlass);
-121--2611318-

Нет является одиночным, поэтому сравнение идентичности всегда будет работать, тогда как объект может подделать сравнение равенства через . _ _ eq _ _ () .

16
ответ дан 23 November 2019 в 04:01
поделиться
>>> () is ()
True
>>> 1 is 1
True
>>> (1,) == (1,)
True
>>> (1,) is (1,)
False
>>> a = (1,)
>>> b = a
>>> a is b
True

Некоторые объекты являются одиночными, поэтому равно с ними, что эквивалентно == . Большинство нет.

7
ответ дан 23 November 2019 в 04:01
поделиться

Примите во внимание следующее:

class Bad(object):
    def __eq__(self, other):
        return True

c = Bad()
c is None # False, equivalent to id(c) == id(None)
c == None # True, equivalent to c.__eq__(None)
28
ответ дан 23 November 2019 в 04:01
поделиться

Во-первых, позвольте мне остановиться на нескольких терминах. Если вы просто хотите получить ответ на свой вопрос, прокрутите вниз до «Ответить на ваш вопрос».

Определения

Идентификатор объекта : Когда вы создаете объект, вы можете назначить его переменной. Затем вы также можете присвоить его другой переменной. И другой.

>>> button = Button()
>>> cancel = button
>>> close = button
>>> dismiss = button
>>> print(cancel is close)
True

В этом случае cancel , close и dismiss все относятся к одному и тому же объекту в памяти. Вы создали только один объект Button , и все три переменные относятся к этому одному объекту. Мы говорим, что cancel , close и dismiss все относятся к идентичным объектам; то есть они относятся к одному единственному объекту.

Равенство объектов : Когда вы сравниваете два объекта, вас обычно не волнует, что они ссылаются на точный тот же объект в памяти. С помощью равенства объектов вы можете определить свои собственные правила сравнения двух объектов. Когда вы пишете if a == b: , вы, по сути, говорите if a .__ eq __ (b): . Это позволяет вам определить метод __ eq __ на a , чтобы вы могли использовать свою собственную логику сравнения.

Обоснование сравнений на равенство

Обоснование: Два объекта имеют одинаковые данные, но не идентичны. (Это не один и тот же объект в памяти.) Пример: Строки

>>> greeting = "It's a beautiful day in the neighbourhood."
>>> a = unicode(greeting)
>>> b = unicode(greeting)
>>> a is b
False
>>> a == b
True

Примечание: я использую здесь строки Unicode, потому что Python достаточно умен, чтобы повторно использовать обычные строки без создания новых в памяти .

Здесь у меня есть две строки Unicode, a и b . У них одинаковое содержимое, но они не являются одним и тем же объектом в памяти. Однако, когда мы сравниваем их, мы хотим, чтобы они сравнивались как равные. Здесь происходит то, что объект unicode реализовал метод __ eq __ .

class unicode(object):
    # ...

    def __eq__(self, other):
        if len(self) != len(other):
            return False

        for i, j in zip(self, other):
            if i != j:
                return False

        return True

Примечание: __ eq __ в unicode определенно реализован более эффективно, чем это.

Обоснование: Два объекта имеют разные данные, но считаются одним и тем же объектом, если некоторые ключевые данные совпадают. Пример: Большинство типов данных модели

>>> import datetime
>>> a = Monitor()
>>> a.make = "Dell"
>>> a.model = "E770s"
>>> a.owner = "Bob Jones"
>>> a.warranty_expiration = datetime.date(2030, 12, 31)
>>> b = Monitor()
>>> b.make = "Dell"
>>> b.model = "E770s"
>>> b.owner = "Sam Johnson"
>>> b.warranty_expiration = datetime.date(2005, 8, 22)
>>> a is b
False
>>> a == b
True

Здесь , У меня есть два монитора Dell, a и b . У них одна и та же марка и модель. Однако они не имеют одинаковых данных и не являются одним и тем же объектом в памяти. Однако, когда мы сравниваем их, мы хотим, чтобы они сравнивались как равные. Здесь происходит то, что объект Monitor реализовал метод __ eq __ .

class Monitor(object):
    # ...

    def __eq__(self, other):
        return self.make == other.make and self.model == other.model

Ответ на ваш вопрос

При сравнении с Нет , всегда использовать не . В Python нет синглтона - в памяти всегда есть только один его экземпляр.

Сравнивая идентичность , это может быть выполнено очень быстро.Python проверяет, имеет ли объект, на который вы ссылаетесь, тот же адрес памяти, что и глобальный объект None - очень и очень быстрое сравнение двух чисел.

Сравнивая равенство ,Python должен проверить, есть ли у вашего объекта метод __ eq __ . В противном случае он проверяет каждый суперкласс в поисках метода __ eq __ . Если он его находит, Python вызывает его. Это особенно плохо, если метод __ eq __ работает медленно и не возвращается сразу же, когда замечает, что другой объект - None .

Разве вы не реализовали __ eq __ ? Тогда Python, вероятно, найдет метод __ eq __ на объекте и воспользуется им вместо него, который в любом случае просто проверяет идентичность объекта.

При сравнении большинства других вещей в Python вы будете использовать ! = .

133
ответ дан 23 November 2019 в 04:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: