2015-02-11 2 views
0

Я пытаюсь реализовать приоритетную очередь в Python. Я следую example, который я нашел в Интернете. Класс Skill переопределяет метод __cmp__, так что очередь приоритетов может сама заказывать. Я получаю сообщение об ошибке, когда я бегу:Приоритетная очередь не распознает функцию __cmp__ в Python

TypeError: unorderable types: Skill() < Skill() 

я нашел несколько примеров в Интернете, которые говорят, до тех пор, как вы перегрузить метод __cmp__() очередь приоритет должен быть хорошим.

try: 
    import Queue as Q # ver. < 3.0 
except ImportError: 
    import queue as Q 

class Skill(object): 
    def __init__(self, priority, description): 
     self.priority = priority 
     self.description = description 
     print ('New Level:', description) 
     return 
    def __cmp__(self, other): 
     return cmp(self.priority, other.priority) 

q = Q.PriorityQueue() 

q.put(Skill(5, 'Proficient')) 
q.put(Skill(10, 'Expert')) 
q.put(Skill(1, 'Novice')) 

while not q.empty(): 
    next_level = q.get() 
    print ('Processing level:', next_level.description) 

В данный момент я использую Python 3.4.1 на своем компьютере.

+1

Это ваш фактический отступ? Также обратите внимание, что '__cmp__' игнорируется в 3.x и заменяется богатым сравнением: https://docs.python.org/3/reference/datamodel.html#object.__lt__. См. http://stackoverflow.com/q/8276983/3001761 – jonrsharpe

+0

Это мой фактический отступ. Я новичок в Python, это еще один отступ? Поэтому я должен использовать богатое сравнение, а не cmp? – morganw09dev

+0

Отступы имеют решающее значение для Python, код, который вы опубликовали, не будет работать. Да, вы должны использовать богатые методы сравнения, если вы пишете для 3.x. – jonrsharpe

ответ

2

__cmp__ был удален в Python3, вы должны использовать богатые методы сравнения Dunder вместо __lt__, __le__, __eq__, __ne__, __gt__, __ge__.

Они работают следующим образом:

a < b # a.__lt__(b) 
a <= b # a.__le__(b) 
a == b # a.__eq__(b) 
a != b # a.__ne__(b) 
a > b # a.__gt__(b) 
a >= b # a.__ge__(b) 

Вы также можете использовать классовый декоратор functools.total_ordering, который позволяет указать __eq__ и любой из __lt__, __le__, __gt__, __ge__, и он будет выводить остаток богатых методов сравнения.

import functools 

@functools.total_ordering 
class NewNumber(object): 
    def __init__(self, num): 
     self.num = num 
    def __lt__(self, other): 
     return self.num < getattr(other, 'num', other) 
     # fancy way of doing self.num < other.num if other.num exists, 
     # else to do self.num < other 
    def __eq__(self, other): 
     return self.num == getattr(other, 'num', other) 
1

cmp и __cmp__ были использованы только в Python 2.x; они больше не существуют в Python 3.x. В настоящее время вы непосредственно перегружаете операторов сравнения, применяя __eq__, __ne__, __lt__, __gt__, __ge__ и __le__.

Вы можете прочитать об этом изменения на Что нового в Python 3.0 страницы под Ordering Comparisons:

cmp() функция не должна рассматриваться как нет, а особый метод __cmp__() больше не поддерживается. Используйте __lt__() для сортировки, __eq__() с __hash__() и другими богатыми сопоставлениями по мере необходимости.