Почему в Python невозможно перегрузить оператор сравнения идентичности? Любой другой оператор сравнения можно настроить, так почему бы не сравнить идентичность?
Цель перегрузки оператора идентификации
Ответы (3)
Языки программирования, поддерживающие объекты с изменяемым состоянием, обычно предоставляют оператор, который может проверить, действительно ли два объекта являются одним и тем же объектом. «Одинаковые» в данном случае означает, что объекты на самом деле являются одним и тем же объектом (например, одним и тем же блоком байтов в памяти (или тем же способом, выбранным разработчиками компилятора для представления объектов). Однако для многих типов структур данных существуют другие типы отношений эквивалентности, которые могут быть более заметными для программиста. Например, при наличии интерфейса List программист может заботиться только о том, содержат ли два списка эквивалентные элементы в одном и том же порядке. Это действительно имеет значение только в том случае, если есть некоторые способ различения двух списков с эквивалентными элементами.Поскольку многие языки программирования поддерживают изменяемое состояние, операции, которые изменяют состояние объекта, являются именно таким способом, которым такие объекты могут быть различимы.
Например, учитывая изменяемую реализацию списков, мы могли бы иметь:
x = make a list of 1 2 3
y = x
z = make a list of 1 2 3 4
x same as y? yes.
x equal to y? yes.
x same as z? no.
x equal to z? no.
add 4 to end of x
x same as y? yes.
x equal to y? yes.
x same as z? no.
x equal to z? yes. ##
В функциональном языке программирования, который не имеет изменяемого состояния, или даже на языке, который имеет изменяемое состояние, но в котором мы используем функциональные стили, мы не будем деструктивно изменять такой список, а скорее будем добавить операция вернет новый список (возможно, разделяя структуру с другими). В таком случае можно было бы иметь только один список для любой последовательности элементов, поэтому мы могли бы иметь:
x = make a list of 1 2 3
y = x
z = make a list of 1 2 3 4
x same as y? yes.
x equal to y? yes.
x same as z? no.
x equal to z? no.
x' = add 4 to end of x
x same as y? yes.
x equal to y? yes.
x same as z? no.
x equal to z? no.
x same as x'? no.
x equal to x'? no.
x' same as x? no.
x' equal to x? no.
x' same as z? yes. ## or no, depending on implementation
x' equal to z? yes.
x' same as x'? yes.
x' equal to x'? yes.
Дело в том, что
x same as y? yes.
x equal to y? yes.
x same as z? no.
x equal to z? no.
остается неизменным во всем, может быть полезно при рассуждении о поведении программ.
Когда мы программируем объектно-ориентированным способом, идентичность объекта является важной концепцией и действительно является одним из примитивов языка, точно так же, как логические операторы или числовое сравнение. Если его можно переопределить, целый класс оптимизаций не может быть выполнен, и вы можете ввести некоторые довольно сложные для отслеживания ошибки. Например, рассмотрим (возможно, надуманный пример):
# frob x and y, but never frob an object twice
frobBoth x y
if x same as y # **
frob x
else
frob x
frob y
end if
Если бы вы могли переопределить same as
, то вы не могли бы frob
одновременно x
и y
, потому что same as
мог бы вернуть истину, даже если x
и y
не являются одним и тем же объектом.
В языках, где идентификация объекта может быть важной, должен быть оператор идентификации объекта, который нельзя переопределить. Также обычно полезно ввести оператор равенства, который можно каким-либо образом переопределить, чтобы было легко проверить, эквивалентны ли два объекта некоторым полезным способом (и это будет зависеть от типа объекта).
- В Python оператором идентичности является
is
, а оператором равенства -==
, который можно настроить с помощью метода__eq__
. - В качестве другого примера, в Java оператор идентичности
==
, а оператор равенстваObject.equals(Object)
.
Стоит отметить, что во многих языках реализация оператора равенства по умолчанию является идентификатором объекта. Это может быть приятно, потому что идентичность объекта обычно проверяется гораздо быстрее, чем другие, более сложные отношения равенства.
Вы не можете переопределить 'is', потому что он проверяет, являются ли два объекта одним и тем же объектом, сравнивая их адреса в памяти (т. Е. Сравнение указателей).
is
является сравнением идентичности, не означает, что он не может быть переопределен. Например, метод equals
по умолчанию в Java выполняет сравнение идентичности, но его можно переопределить. Конечно, Java по-прежнему предоставляет ==
, который нельзя переопределять, и обеспечивает сравнение идентичностей. Я думаю, что, возможно, здесь отсутствует предпосылка о том, что непревзойденное сравнение идентичности очень желательно, а is
принадлежит Python.
- person Joshua Taylor; 19.01.2014
Проще говоря, потому что цель оператора идентификации - проверить идентичность. Идентичность означает «то, чем на самом деле является объект». Весь смысл оператора состоит в том, чтобы иметь возможность проверить, «действительно ли два объекта» являются одним и тем же объектом, а не то, «хотят ли они» считаться одним и тем же в соответствии с их собственными правилами.
==
имеет смысл. В конце концов, должен быть хотя бы один оператор, которому вы можете доверять. знак равно - person Ry-♦   schedule 18.01.2014is
принадлежит Python. Важно иметь непереопределяемые операторы для определенных вещей (например, логических операций). Однако вы можете настроить поведение==
. У вас есть конкретный вариант использования, когда вы чувствуете необходимость переопределитьis
, но не можете предоставить__eq__
метод для настройки==
? - person Joshua Taylor   schedule 19.01.2014