重写自定义类的枚举

Overriding enumerate for custom class

提问人:Mate de Vita 提问时间:8/27/2023 更新时间:8/27/2023 访问量:42

问:

我有一个自定义类,它本质上是一个列表,但负索引是有效的索引,而不是引用列表后面的元素。

from collections.abc import Sequence


class MultiFloorPlan(Sequence):
    def __init__(self):
        super().__init__()
        self._floors = []
        self._subfloors = []

    def __eq__(self, other):
        if not isinstance(other, MultiFloorPlan):
            return NotImplemented
        return self._subfloors == other._subfloors and self._floors == other._floors

    def _reindex(self, floor):
        if floor >= 0:
            return self._floors, floor
        return self._subfloors, -floor - 1

    def __len__(self):
        return len(self._subfloors) + len(self._floors)

    def __getitem__(self, floor):
        floor_list, floor = self._reindex(floor)
        return floor_list[floor]

    def __delitem__(self, floor):
        floor_list, floor = self._reindex(floor)
        del floor_list[floor]

    def __iter__(self):
        for plan in self._subfloors:
            yield plan
        for plan in self._floors:
            yield plan

    def __reversed__(self):
        for plan in reversed(self._floors):
            yield plan
        for plan in reversed(self._subfloors):
            yield plan

    def __contains__(self, value):
        return value in self._subfloors or value in self._floors

    def append(self, subfloor=False):
        if subfloor:
            return self._subfloors.append(None)  # For this example we append a dummy None
        return self._floors.append(None)         # value instead of an actual Plan instance

是否有可能让内置的返回地板索引,而不是将值转移到非负整数?例:enumerate

mfp = MultiFloorPlan()
for _ in range(5):
    mfp.append(subfloor=False)
    mfp.append(subfloor=True)

for floor, _ in enumerate(mfp):
    print(floor)
# This prints 0 1 2 3 4 5 6 7 8 9, but I'd like it to print -5 -4 -3 -2 -1 0 1 2 3 4
python-3.x 枚举

评论

0赞 mkrieger1 8/27/2023
你不能改变什么,但你可以改变你的类在循环中的行为方式。你确定你不只是想要吗?enumerateforfor floor in mfp: print(floor)
1赞 user3840170 8/27/2023
为什么不直接使用自定义生成器方法呢?比较词典,它有一个方法而不是重载。.items()enumerate
0赞 Mate de Vita 8/28/2023
@user3840170 这可能是我要做的,还在数组上定义了自己的枚举方法。我只是想知道是否有办法像其他内置函数和运算符(、、、等)一样覆盖内置函数。numpyenumeratein[]getattr

答:

2赞 Blckknght 8/27/2023 #1

内置函数在任意迭代器上运行,因此它不能以特殊方式运行您的类。但是,聪明的用户可以生成您想要的结果,他们只需要通过传入适当的起始索引来正确设置它。您可以在类中提供该设置,并使用以下方法:enumerateenumerate

def enumerate(self):
    return enumerate(self, -len(self._subfloors))