为什么python中允许使用浮点切片(slice(0,1,0.1)),但调用索引方法(slice(0,1,0.1).indices)会引发TypeError?

问题描述 投票:4回答:1

示例:在Python 3.7.7中slice(0,1,0.1)没问题,但是slice(0,1,0.1).indices(10)引发了Type Error

我想知道这种行为的基本思维过程是什么。为什么可以构造float切片,但不能对其调用indices方法呢? indices的用例是什么?

对于上下文:我了解浮动切片的用例-我自己一个人。我正在实现一个对象,该对象表示由有限的一组支撑点定义的任意尺寸的参数化分段线性函数。

python slice
1个回答
1
投票
当我们以方括号表示法使用对象时,解释器会生成

tl; dr slice”对象,并且允许它们是任意的允许我们设计使用它们的代码。但是,由于内置列表依赖indices()来正常运行,因此该方法必须返回兼容列表的值(即整数),如果不能,则抛出错误。


当你做的时候

my_obj[1:3:2]

解释器将其翻译为*为

my_obj.__getitem__(slice(1, 3, 2))

这在使用列表时最明显,当给出切片时,列表具有特殊的行为,但是这种行为也是各种流行库(例如numpy.arraypandas.Dataframe)中的其他数据类型。这些类实现了自己的__getitem__()方法,它们具有自己的特殊方式来处理切片。

现在,内置列表可能使用slice.indices()将整个片分解为一组可以访问的单个索引,然后可以组合在一起并返回。列表索引只能是整数,它们不希望破坏此功能,因此最一致的解决方法是在slice.indices()无法生成整数列表时引发错误。

但是,它们不能将slice限制为仅具有那些值,因为这是其他用户定义的类可能要使用的解释器生成的对象。如果您设计这样的对象:

class myGenerator:
    def __getitem__(self, s):  # s is a slice
        def gen():
            i = s.start
            while i < s.stop:
                yield i
                i += s.step
        return list(gen())

h = myGenerator()
print(h[1:4:.25])
# [1, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.25, 3.5, 3.75]
print(h[0:1:0.1])
# [0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7, 0.7999999999999999, 0.8999999999999999, 0.9999999999999999]

然后,它可以根据需要选择使用切片符号,因此我们可以为其建立自定义行为。但是,如果我们将slice.indices()改为使用它,那么它将破坏内置的list-因此,python不允许我们这样做。


*从技术上讲,对于许多内置函数,python解释器可能会采用快捷方式并执行硬编码的例程,而不是实际将符号转换为函数调用并执行它们。但是出于我们的目的,类比已经足够好了,因为它确实对用户生成的对象起作用。

© www.soinside.com 2019 - 2024. All rights reserved.