Ожидается взаимное исключение с операторами сравнения

Я не гений программирования, но как раз в начале этого года, когда меня учили логике высказываний, мой учитель сказал мне (и это было совершенно очевидно), что если P истинно, то не (P) или ~P ложно, и наоборот, если P было False.

Читая документы Python о создании пользовательских объектов, я обнаружил, что они утверждают, что a==b является True, не означает, что a!=b является False. Это сбило меня с толку, так как я думал, что != было отрицанием ==, и поэтому всякий раз, когда вычисление с помощью == возвращало логический результат, выражение != всегда оценивалось как противоположное... И, насколько я знаю, not(True) оценивается как False и not(False) оценивается как True. Может кто-нибудь, пожалуйста, помогите мне понять, как это происходит? Может быть, с примером?

Я прочитал об этом праве здесь

цитирую:

Истинность x==y не означает, что x!=y ложно.


person RGS    schedule 24.05.2014    source источник


Ответы (2)


Это потому, что это операторы, которые могут быть реализованы отдельно, и сами операторы (на высоком уровне) не диктуют, что если x==y истинно, то x!=y ложно (их можно реализовать так, что отношение не следует).

Ключом является заявление в документе, которое следует за тем, что:

Соответственно, при определении __eq__() следует также определить __ne__(), чтобы операторы вели себя так, как ожидается

Когда оба реализованы, между операторами существует явная связь.

person khampson    schedule 24.05.2014
comment
Значит ли это, что такое поведение не является самоисключающим, когда мы говорим о пользовательских объектах? - person RGS; 25.05.2014
comment
Нет. Хотя настройка по существу является причиной отсутствия подразумеваемых отношений, поскольку подразумеваемых отношений нет, всегда следует помнить о задокументированном поведении. (За кулисами необходимо определить как __eq__(), так и __ne__(), чтобы получить ожидаемое поведение. - person khampson; 25.05.2014
comment
Ok. так было бы правильно определить __ne__() как not(self.__eq__())? - person RGS; 25.05.2014
comment
Конечно. Суть в том, что если вы определяете это таким образом, вы явно устанавливаете отношения; это просто не сделано для вас неявно. - person khampson; 25.05.2014
comment
Ok. Спасибо за помощь. - person RGS; 25.05.2014
comment
К вашему сведению, если вы хотите, чтобы python заполнил подразумеваемые отношения, используйте functools.total_ordering - person roippi; 25.05.2014

Во многом это просто потому, что мы можем делать глупости:

class MessedUpShizzle:
    def __eq__(self, other):
        return True

    def __ne__(self, other):
        return True

MessedUpShizzle() == MessedUpShizzle()
#>>> True

MessedUpShizzle() != MessedUpShizzle()
#>>> True

Если вам интересно, для чего это if для, я полагаю, что это в основном для симметрии (и, следовательно, красивая реализация). Учтите, что x < y и x >= y не обратные:

{1} < {2}
#>>> False

{1} >= {2}
#>>> False

поэтому нам нужно отдельно определить __ge__ и __le__.

person Veedrac    schedule 24.05.2014