Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 7, 2011 11:28:52

Alala
От:
Зарегистрирован: 2011-07-14
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

Сравнение объектов, как сделать аккуратнее?

Добрый день!

Дано, объект А, от него отнаследованы объекты 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)
Мне этот вариант нравится, а моему коллеге этот вариант категорически не нравится, т.к. мы вызываем функцию от объекта внутри глобально функции

Вопрос, как все это сделать аккуратнее и не так криво?



Офлайн

#2 Окт. 7, 2011 13:07:32

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Сравнение объектов, как сделать аккуратнее?

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

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

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

p.s. не очень понятно, в чем проблема вызова метода в глобальной функции. Мне кажется вполне допустимо и часто используется.



Офлайн

#3 Окт. 7, 2011 13:16:58

magnet85
От:
Зарегистрирован: 2009-04-13
Сообщения: 91
Репутация: +  2  -
Профиль   Отправить e-mail  

Сравнение объектов, как сделать аккуратнее?

Попробовать переопределить метод __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



Офлайн

#4 Окт. 7, 2011 13:58:11

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

Сравнение объектов, как сделать аккуратнее?

Скорее уж __cmp__ , судя по первому посту этого треда. Хотя может быть несколько методов типа __eq__, __lt__, __gt__ и так далее.
Подробности здесь: http://docs.python.org/reference/datamodel.html?highlight=__cmp__#basic-customization



Офлайн

#5 Окт. 7, 2011 14:42:54

Alala
От:
Зарегистрирован: 2011-07-14
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

Сравнение объектов, как сделать аккуратнее?

doza_and
Мы можем пологать, что оба аргумента всегда приходят одинакового типа



Офлайн

#6 Окт. 7, 2011 14:56:18

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Сравнение объектов, как сделать аккуратнее?

А тогда в чем проблема - переопределяете __cmp__ и все. Или если хотите в ваших обозначениях

class T1:
def cmp(self,obj):
return ....
class T2:
def cmp(self,obj):
return ....

# comparision:
a1=T1()
a2=T1()
a1.cmp(a2)
тут даже наследование нигде не требуется



Офлайн

#7 Окт. 10, 2011 21:07:19

Alala
От:
Зарегистрирован: 2011-07-14
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

Сравнение объектов, как сделать аккуратнее?

всплыли факты, которые не позволяют просто переопределить __cmp__()
некоторые параметры сравнения зависят от внешнего мира =(

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

получилась интересная фигня

def cmp(self, other):
...

o1.cmp(o1,o2)
есть идеи почему такой код может работать? может ли быть дело в областях видимости?
может в чем-то еще?



Офлайн

#8 Окт. 10, 2011 21:59:14

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Сравнение объектов, как сделать аккуратнее?

Так а в чем фигня? Вы имеете ввиду что у вас количество аргументов неправильное?
Если

def cmp(self,other)
то
o1.cmp(o2)



Офлайн

#9 Окт. 10, 2011 22:26:18

Alala
От:
Зарегистрирован: 2011-07-14
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

Сравнение объектов, как сделать аккуратнее?

doza_and
фигня в том, что это работает и я не понимаю почему



Офлайн

#10 Окт. 10, 2011 22:31:39

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Сравнение объектов, как сделать аккуратнее?

Приведите пожалуйста полный код который работает



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version