Найти - Пользователи
Полная версия: Сравнение объектов, как сделать аккуратнее?
Начало » Python для новичков » Сравнение объектов, как сделать аккуратнее?
1 2
Alala
Добрый день!

Дано, объект А, от него отнаследованы объекты X, Y, Z.
Есть глобальная функция сравнения двух объектов(comp(o1, o2)). Раньше объекты могли быть только типа А, так что проблем не было. Теперь, они могут быть разных типов(А, X, Y, Z). Соответственно выяснилось, что правила сравнения для Х немного отличаются от правил сравнения для остальных объектов.

Какой вариант решения наиболее правильный/аккуратный/меньше проблем впоследствии?
1) Добавить условие в функцию comp(), чтобы для объекта Х идти по другой ветке.
2) Сделать две функции сравнения common_comp() и X_comp(), и, соответственно вызывать одну из них в зависимости от типа объекта и других параметров
3) Добавить функцию сравнения в А, а в Х ее переопределить, тогда будет получаться что-то типо такого:

def comp(o1, o2)
return o1.comp(o1,o2)
Мне этот вариант нравится, а моему коллеге этот вариант категорически не нравится, т.к. мы вызываем функцию от объекта внутри глобально функции

Вопрос, как все это сделать аккуратнее и не так криво?
doza_and
Ваша функция зависит от типов обоих аргументов. как мне кажется лучше симметричный подход см
http://www.iso.ru/print/rus/document5973.phtml

Это некая смесь подхода 2 и 3. Конкретная реализация зависит от того это 2.x или 3.x.

Кроме того, на мой вкус, это должен быть оператор == а не функция comp

p.s. не очень понятно, в чем проблема вызова метода в глобальной функции. Мне кажется вполне допустимо и часто используется.
magnet85
Попробовать переопределить метод __eq__ у базового класса, типа так (пример с stackoverflow.com):
_NOTFOUND = object()

class Rational(object):
def __eq__(self, other):
for attr in ['numerator', 'denominator']:
v1, v2 = [getattr(obj, attr, _NOTFOUND) for obj in [self, other]]
if v1 is _NOTFOUND or v2 is _NOTFOUND:
return False
elif v1 != v2:
return False
return True
Ed
Скорее уж __cmp__ , судя по первому посту этого треда. Хотя может быть несколько методов типа __eq__, __lt__, __gt__ и так далее.
Подробности здесь: http://docs.python.org/reference/datamodel.html?highlight=__cmp__#basic-customization
Alala
doza_and
Мы можем пологать, что оба аргумента всегда приходят одинакового типа
doza_and
А тогда в чем проблема - переопределяете __cmp__ и все. Или если хотите в ваших обозначениях
class T1:
def cmp(self,obj):
return ....
class T2:
def cmp(self,obj):
return ....

# comparision:
a1=T1()
a2=T1()
a1.cmp(a2)
тут даже наследование нигде не требуется
Alala
всплыли факты, которые не позволяют просто переопределить __cmp__()
некоторые параметры сравнения зависят от внешнего мира =(

решили сделать, как предложил doza_and

получилась интересная фигня
def cmp(self, other):
...

o1.cmp(o1,o2)
есть идеи почему такой код может работать? может ли быть дело в областях видимости?
может в чем-то еще?
doza_and
Так а в чем фигня? Вы имеете ввиду что у вас количество аргументов неправильное?
Если
def cmp(self,other)
то
o1.cmp(o2)
Alala
doza_and
фигня в том, что это работает и я не понимаю почему
doza_and
Приведите пожалуйста полный код который работает
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB