如果在Python中将()发送到生成器*表达式*会发生什么?

2024-04-25 13:30:36 发布

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

我很惊讶地发现, ge=(x*x for x in [1,2,3]) 接受.send方法。与任何其他生成器一样,第一个调用的参数必须是None,但是进一步调用的行为,例如ans=ge.send(99)似乎与ans=next(ge)相同。你知道吗

我的99去哪了?通用电气内部没有屈服表达式,无需赋值。注入的价值是简单地丢弃了(我怀疑),还是有一些神秘的东西?你知道吗

有人看到了吗?你知道吗


Tags: 方法innonesendfor参数表达式next
2条回答

send使用生成器函数创建的等效生成器相同:

def genfunc(outer_iterable):
    for x in outer_iterable:
        yield x*x

ge = genfunc([1, 2, 3])

也就是说,send参数被丢弃。你知道吗

我们可以分解字节码以进一步确认:

import dis

ge=(x*x for x in [1,2,3])

print('Genexp:')
dis.dis(ge)

def genfunc(outer_iterable):
    for x in outer_iterable:
        yield x*x

ge = genfunc([1, 2, 3])

print()
print('Generator function:')
dis.dis(ge)

Output

Genexp:
  3           0 LOAD_FAST                0 (.0)
        >>    3 FOR_ITER                15 (to 21)
              6 STORE_FAST               1 (x)
              9 LOAD_FAST                1 (x)
             12 LOAD_FAST                1 (x)
             15 BINARY_MULTIPLY
             16 YIELD_VALUE
             17 POP_TOP
             18 JUMP_ABSOLUTE            3
        >>   21 LOAD_CONST               0 (None)
             24 RETURN_VALUE

Generator function:
  9           0 SETUP_LOOP              23 (to 26)
              3 LOAD_FAST                0 (outer_iterable)
              6 GET_ITER
        >>    7 FOR_ITER                15 (to 25)
             10 STORE_FAST               1 (x)

 10          13 LOAD_FAST                1 (x)
             16 LOAD_FAST                1 (x)
             19 BINARY_MULTIPLY
             20 YIELD_VALUE
             21 POP_TOP
             22 JUMP_ABSOLUTE            7
        >>   25 POP_BLOCK
        >>   26 LOAD_CONST               0 (None)
             29 RETURN_VALUE

genexp和通过generator函数创建的generator具有非常相似的分解,在这两个函数中,YIELD_VALUE后面紧跟着一个POP_TOP,它丢弃从send发送的任何值。你知道吗

谢谢大家。所以是的,send的arg被丢弃了,但是send被接受这一事实似乎是一个异常。你知道吗

另一个相关的bug已经在这里被注释过了(第32139885页),yield表达式应该在genexps中被禁止,但是它不是。形式ge=((yield x*x) for x in [1,2,3])被接受,并且.send()可以工作。你知道吗

send返回的答案是内部iterable中元素的混合物,send的arg。。。如果我没有弄错的话,GvR写道在python3.8中,这个(yield表达式)将被视为一个错误,在3.7中,它应该表示它已被弃用。(人们一致认为这很混乱。)

但我在python3.7(Anaconda,windows64)中测试了它,没有收到任何弃用警告。无论如何,这似乎是一个真正的错误,而不是一个功能被否决。我相信现在没有什么可说的了。。。你知道吗

JK公司

相关问题 更多 >