gpt4 book ai didi

python - 在 python 中重写 tuple.__len__

转载 作者:行者123 更新时间:2023-12-01 05:13:38 24 4
gpt4 key购买 nike

我想在 python 中原生实现一个不可变类型。我从这里收集的

How to make an immutable object in Python?

最好的方法是覆盖元组。假设我想要一个存储一些额外数据的元组。我会做类似的事情:

class MyTuple(tuple):
def __new__(cls, lst, data):
return tuple.__new__(cls, tuple(lst) + (data, ))

现在我想重写 len 函数:

    def __len__(self):
return tuple.__len__(self) - 1

这对于我家里的 python 版本(Python 2.something,但我不知道是哪个)运行得很好,但在我的办公室计算机(Python 2.7.3)上它会破坏切片:如果我这样做

m = MyTuple([1,2], 0)
print(m[:-1])

我得到 (1, ) 而在家里我会得到 (1, 2) (我实际上没有检查,但将我的问题追溯到这个最小的例如,我认为是这样)。因此,在一种实现中,切片似乎是调用 tuple.__len__ 而在另一种实现中,它是调用 MyTuple.__len__。我不介意任何一种方式,但一致性会很好。

所以我的问题是:是否有一个可靠的解决方案,如果没有,哪些行为将是稳定的?

编辑:正如 Leonardo.Z 所建议的,我的“家”Python 实际上是 Python 3(.4)。我一直在尝试一个新的IDE,并没有关注它使用的是哪个Python。

最佳答案

这是由于Python2和Python3的切片实现不同造成的。

在 Python3 中,obj[x:y] 始终等于 obj.__getitem__(slice(x,y))。但在Python2中,由于历史原因,一些内置类型(包括元组)使用__getslice__方法实现切片运算符。

__getslice__ 使用 __len__ 方法,__getitem__ 则不使用。

只需在 Python2 和 Python3 中运行以下代码,您就会明白原因。

from __future__ import print_function

class MyTuple(tuple):
def __new__(cls, lst, data):
return tuple.__new__(cls, tuple(lst) + (data, ))
def __len__(self):
return tuple.__len__(self) - 1

def __getitem__(self, key):
print("__getitem__() is called. start:%s, end:%s" % (key.start, key.stop))
return super(MyTuple, self).__getitem__(key)

def __getslice__(self, start, end):
print("__getslice__() is called. start:%s, end:%s" % (start,end))
return super(MyTuple, self).__getslice__(start,end)

m = MyTuple([1,2], 0)

print(m[:-1])

根据Python官方文档,当您更改子类中的__len__实现时,应该覆盖__getslice__()方法。引用:

The official doc about object.__getslice__.

关于python - 在 python 中重写 tuple.__len__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23673314/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com