在Python 2.5中重写reversed(...)
我需要为我的类写一个自定义的 __reverse__
函数,因为我在 App Engine 上部署它,所以必须支持 Python 2.5
。请问有没有什么 __future__
的导入或者其他解决办法可以用?
我不能通过继承 list
来实现,因为我需要我的类是 dict
的子类。
编辑:
使用 OrderedDict
也解决不了问题,因为 dict
的键和 list
的项并不相同。
我想创建的对象是这样的:
我的对象需要提供和
list
一样的属性,也就是说要支持iter(obj)
和reverse(obj)
。这些元素必须是一个特殊第三方类的实例。
每个元素都要和一个键关联。
在内部,需要通过这些键来访问这些对象。这就是我想把它们放在一个映射中的原因。
我已经把我的实现修改为 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)
编辑 2:
现在我的类是 list
的子类,我的问题解决了。
2 个回答
从2.6版本开始,你可以创建一个自定义的 __reversed__
方法,这样就能让 reversed
函数正常工作。但在2.5版本及以下,你不能这样做。不过,你可以通过实现序列协议来让你的自定义类也能和 reversed
一起使用。序列协议就是你需要实现两个方法:__len__
和 __getitem__
。
另外一种方法是用一个自定义的函数来替代内置的 reversed
函数,这样可以让你的自定义类有不同的处理方式。可以这样做:
originalReversed = reversed
def myReversed ( seq ):
if isinstance( seq, MyCustomClass ):
# do something special
else:
return originalReversed( seq )
reversed = myReversed
不过,我不太推荐这种做法,因为这会改变内置函数的正常行为,可能会让其他用户感到困惑。所以,最好还是实现序列协议,这样 reversed
就能正常工作了。
在2.5版本中,__reversed__
这个功能是不支持的。所以如果你真的需要自定义你集合的反向顺序,你唯一的办法就是修改你调用reversed
的地方,换成其他的方法。
不过我很好奇:如果你是在子类化dict
(字典),那么字典里的项目顺序本来就是随意的,那在这种情况下,反向(reversed)又是什么意思呢?