2010-10-16 5 views
0

Мне нужна пользовательская функция __reverse__ для моего класса, которую я развертываю в App Engine, поэтому она должна работать с Python 2.5. Есть ли __future__ импорт или обходной путь, который я мог бы использовать?Переопределить обратное (...) в Python 2.5

Подкласс list не будет работать, так как мне нужен мой класс для подкласса dict.

EDIT:

Использование OrderedDict не решат проблемы, так как dict ключей не совпадают так же, как list пунктов.

Это объект, который я пытаюсь создать:

  1. Мой объект должен предоставить те же атрибуты, как list, то есть поддержка iter(obj) и reverse(obj).

  2. Элементы должны быть экземплярами специального третьего класса.

  3. Каждый элемент связан с ключом.

  4. Внутренне необходимо получить доступ к этим объектам с помощью их ключей. Вот почему я поместил их в картографию.

Я пересмотрел свое осуществление, чтобы быть list подкласс вместо dict подкласса, так вот что я сейчас:

class Foo(list): 

    pat = {} 

    def __init__(self): 
     for app in APPS: # these are strings 
      obj = SpecialClass(app) 
      self.append(obj) 
      self.pat[app] = obj 

    def __getitem__(self, item): 

     # Use object as a list 
     if isinstance(item, int): 
      return super(Foo, self).__getitem__(item) 

     # Use object as a dict 
     if item not in self.pat: 
      # Never raise a KeyError 
      self.pat[item] = SpecialClass(None) 
     return self.pat[item] 

    def __setitem__(self, item, value): 
     if isinstance(item, int): 
      return self.pat.__setitem__(item, value) 
     return super(Foo).__setitem__(item, value) 

EDIT 2:

Теперь, когда мой class является подклассом list, моя проблема решена.

+0

Я что-то пропустил; теперь, когда ваш класс является подклассом списка, почему вы не переопределяете и не используете list.reverse() hmmm? – mouad

+0

@tzzzzz Теперь я могу использовать 'reverseed()'. Обратите внимание, что 'list.reverse()' изменяет список ** на месте **, что не то, что я хочу. Я только хотел поддержать встроенный 'reverseed()'. –

ответ

2

__reversed__ не поддерживается в 2.5, поэтому ваш единственный вариант, если вам действительно нужно настроить обратный порядок вашей коллекции, заключается в изменении мест, которые вы называете reversed, чтобы использовать что-то еще.

Но мне любопытно: если вы подклассифицируете dict, тогда порядок элементов произволен в любом случае, так что в этом случае означает обратное?

+0

Чтобы ответить на ваш вопрос: я сохраняю две коллекции в одном объекте: последовательность (на самом деле «список») и сопоставление (которое является подзадачей 'dict', я использую его как' self') , Затем сторонняя библиотека использует этот объект (который по сути является макетным списком), и он ожидает список. Итак, у меня есть собственный метод '__iter__', который выполняет итерацию по коллекции последовательностей (' pat = []; __iter__ = lambda self: iter (self.pat) '), но я не могу обрабатывать' reverse (my_object) 'с что. Тем не менее, возможно, я должен подклассифицировать «список» и сохранить свои сопоставленные данные в атрибуте и использовать пользовательские методы '__ {get, set} item__'? –

+0

В списке и dict содержатся одни и те же клавиши? Не могли бы вы использовать OrderedDict? – Daenyth

+0

@Daenyth Нет, но dict содержит те же ** значения **, что и элементы списка. –

1

Создание пользовательского __reversed__ возможно только с версии 2.6, поэтому вы не можете просто реализовать это и иметь reversed, работающий в версии 2.5. В 2.5 и ниже вы можете, однако, сделать свой пользовательский класс все еще работающим с reversed путем реализации протокола последовательности (то есть реализовать как __len__, так и __getitem__).

Другой вариант заключается в замене встроенной функции reversed на пользовательскую функцию, которая будет обрабатывать ваш пользовательский класс по-разному. Это может работать так:

originalReversed = reversed 
def myReversed (seq): 
    if isinstance(seq, MyCustomClass): 
     # do something special 
    else: 
     return originalReversed(seq) 
reversed = myReversed 

Однако, я бы не рекомендовал, что, как она изменяет нормальное поведение встроенных функций (очевидно) и может запутать других пользователей ..Поэтому вы должны использовать протокол sequnce для работы reversed.