何时以及如何将“slice(obj)”用于非“int”/“None”类型?

2024-04-25 19:18:23 发布

您现在位置:Python中文网/ 问答频道 /正文

在Python 3中,以下代码不会产生错误:

slice(10.0)

但以下情况确实如此:

range(10.0)

如果我尝试使用slice(float)对象,它也会失败:

list(range(20))[slice(10.0)]

出现以下错误:

TypeError: slice indices must be integers or None or have an __index__ method

表示slice()可以与实现__index__方法的其他对象一起使用。你知道吗

何时/如何对非int/None类型使用slice(obj)?你知道吗

为什么在实例化slice()对象时允许使用float数字? 我能指望slice(float)(和slice(float, float)slice(float, float, float))在python3中从不抱怨实例化吗?你知道吗

编辑:

这似乎与PEP357https://docs.python.org/2.5/whatsnew/pep-357.html有关

但是,我不清楚除了在NumPy中实现高级索引之外,它是否还有其他用途。你知道吗

EDIT3:EDIT2基本上包含了接受答案的第二部分,但有一些语法错误,所以它被删除了


Tags: or对象实例代码noneindex错误情况
1条回答
网友
1楼 · 发布于 2024-04-25 19:18:23

是的,您可以将任何类型的对象传递给slicedocumentation没有提到slice参数类型的限制,source code for slice's constructor只说“start、stop和step是python对象”。你知道吗

list(range(20))[slice(10.0)]拒绝具有float参数的slice对象,但这似乎是特定于列表类型的。数据模型本身在调用__getitem__之前不执行隐式类型检查。您可以编写自己的自定义类来接受更多非传统的切片。示例:

>>> class Fred:
...     def __getitem__(self, idx):
...         return "baz"
...
>>> x = Fred()
>>> print(x[slice("Foo", "Bar")])
baz
>>> print(x[1.0: -10.5])
baz

至于是否有一个实际的理由允许非整数切片,没有想到。。。但是Python社区有一个“我们都是成年人”的文化规范。也就是说,有些东西不应该因为没有明显的实际应用而被禁止。如果有人想做一些看起来很愚蠢的事,那么在其他条件相同的情况下,我们应该让他们做。你知道吗


我们已经确定用户定义的类型可以接受他们想要的任何类型的切片。但是如果你想用不寻常的切片来切片内置类型呢?不能更改列表类型的实现来删除它所做的类型检查。__index__作为一种定义可用于切片列表的新类型的方法非常方便。例如

>>> class Begin:
...     def __index__(self):
...         return 0
...
>>> class End:
...     def __index__(self):
...         return -1
...
>>> list(range(20))[slice(Begin(), End())]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]

相关问题 更多 >