gpt4 book ai didi

Python __index__ 和评估顺序

转载 作者:行者123 更新时间:2023-12-01 06:37:02 25 4
gpt4 key购买 nike

我期望下面的两个代码返回相同的结果,因为 https://docs.python.org/3.7/reference/expressions.html#evaluation-order 。然而,在第二种情况下,Counter 类中的 __index__ 看起来是在 __call__ 之后调用的。是因为 __index__ 仅在到达 ] 时才被调用吗?或者还有其他解释吗?

class Counter:
def __init__(self, start=0):
self._i = start

def __call__(self, step:int=None):
if step is not None:
self._i += step
return self._i

def __index__(self):
return self._i

data = list(range(0, 10))

i = Counter(0)
data[i():i(3)]

返回[0,1,2]

i = Counter(0)
data[i:i(3)]

返回[]

PS:Counter 类的目标是允许类似于 python < 3.8 中的赋值语法

i = 0
data[i: (i := i+3)]

最佳答案

data[i:i(3)] 相当于 data.__getitem__(slice(i, i(3)));在 data.__getitem__ 体内实际需要切片的起始元素之前,i.__index__ 不会被调用,但在 i(3) 之后 已经将 i._step 增加到 3。因此求值的顺序类似于:

  1. 数据[i:i(3)]
  2. i(3) 计算为 3
  3. 构建切片 slice(i,3)
  4. data.__getitem__内部,需要i的整数值,因此调用i.__index__,返回3。<

您可以通过反汇编索引操作来看到这一点:

>>> import dis
>>> dis.dis('data[i:i(3)]')
1 0 LOAD_NAME 0 (data)
2 LOAD_NAME 1 (i)
4 LOAD_NAME 1 (i)
6 LOAD_CONST 0 (3)
8 CALL_FUNCTION 1
10 BUILD_SLICE 2
12 BINARY_SUBSCR
14 RETURN_VALUE

首先调用i(3)(在偏移量8处),然后构建切片(在偏移量10处),最后调用data.__getitem__(在偏移 12)。

关于Python __index__ 和评估顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59616123/

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