5

У меня есть int-производный класс с перегруженным оператором сравнения.Доступ к исходному int-сравнению из int-производного класса с перегруженным оператором сравнения

В теле перегруженных методов мне нужно использовать оригинальный оператор.

Игрушка пример:

>>> class Derived(int): 
...  def __eq__(self, other): 
...   return super(Derived, self).__eq__(other) 

отлично работает с Python 3.3+, но терпит неудачу с Python 2.7, за исключением AttributeError: 'super' object has no attribute '__eq__'.

Я могу думать о нескольких walkarrounds, которые я не нашел очень чистый:

return int(self) == other 

требует создания нового int объекта просто сравнить его, в то время как

try: 
    return super(Derived, self).__eq__(other) 
except AttributeError: 
    return super(Derived, self).__cmp__(other) == 0 

разделяет поток управления на основе на версию Python, которую я нахожу ужасно грязной (так что явным образом проверяю версию Python).

Как я могу получить доступ к первоначальному целочисленному сравнению элегантным способом работы с Python 2.7 и 3.3+?

+1

Вы можете получить доступ к 'int' сравнивая метод с помощью' супер .__ eq__'. Тем не менее, в зависимости от встроенных методов сравнения типов python реализованы разные методы. Поэтому python2 'super.eq' требует 1 аргумент (другой), тогда как python3 требует 2 (self и other) – infotoni91

+0

Вы считаете, что' int (self) == int (other) 'слишком беспорядочно? – Phillip

+0

@Phillip создает еще один объект, чем 'int (self) == other' – abukaj

ответ

0

Я считаю, что перед определением класса вы должны определить __eq__ в int. Например:

int = 5 
def int.__eq__(self, other): 
    return self.real == other 
IntDerived = Derived(int) 

Это должно дать super класс атрибут __eq__.


EDITED


Основная идея работала, но это было доведено до моего сведения, что код не работает. Итак: улучшен код:

class Derived(int): 
    def __eq__(self, other): 
     return self.real == other 

Int = 5 
D = Derived(Int) 
D.__eq__(4) #Output: False 
D.__eq__(5) #Output: True 
+1

Это не питон. – Goyo

+0

@ GreenHawk1220 Я приму ответ, если вы поместите метод '__eq __()' в определение класса Derived (и запустите его в Python). Идея доступа к атрибуту '.real' работает, но код не является Python. – abukaj

+0

Обновленный код работал для меня. – GreenHawk1220

2

Python 2 и 3 значительно отличаются друг от друга, поэтому я думаю, что вы должны укусить пулю и проверить версии. Этого можно ожидать только в том случае, если вы пытаетесь написать код, который работает на обоих (рано или поздно в моем опыте вы найдете что-то, что вам нужно исправить). Чтобы избежать какого-либо влияния на производительность, вы можете сделать что-то вроде:

from six import PY2 

class Derived(int): 
    if PY2: 
     def __eq__(self, other): 
      return super(Derived, self).__cmp__(other) == 0 
    else: 
     def __eq__(self, other): 
      return super(Derived, self).__eq__(other) 

Это то, что я сделал бы. Если бы я действительно хотел подкласс int ...

Если вы действительно не хотите, может быть, вы могли бы попробовать:

class Derived(int): 
    def __eq__(self, other): 
     return (self^other) == 0 

Очевидно, что если вы заботитесь о производительности вы должны сделать некоторые профилирование с остальная часть вашего кода и выясните, является ли какой-либо из них значительно хуже ...

+0

Мне нравится последний подход, однако он не работает, когда 'other' является float – abukaj

0

с использованием hasattr избегает создания нового объекта int, ловя исключение или явно проверки версии Python.

Приведенный ниже код работает как на Python 2.7, так и на 3.3+:

class Derived(int): 
    def __eq__(self, other): 
     return super(Derived, self).__cmp__(other) == 0 if hasattr(Derived, "__cmp__") else super(Derived, self).__eq__(other) 
1

Обе версии реализовать __xor__ метод, вы можете попробовать это:

class Derived(int): 
    def __eq__(self, other): 
     return not super(Derived, self).__xor__(other) 
+0

Мне нравится ответ. Не очень чистый и не работает со сравнением с float. Кроме того, я думаю, что нет необходимости создавать объект 'super',' self' достаточно. 'self^other' может быть еще проще. – abukaj