代码之家  ›  专栏  ›  技术社区  ›  Kelly Bundy

打印(*a,a.pop(0))是如何变化的?

  •  7
  • Kelly Bundy  · 技术社区  · 3 年前

    此代码:

    a = [1, 2, 3]
    print(*a, a.pop(0))
    

    Python3.8打印 2 3 1 pop 拆包前)。
    1 2 3 1 (请问 流行音乐

    是什么导致了这种变化?我没有在房间里找到它 changelog .

    list display

    a = [1, 2, 3]
    b = [*a, a.pop(0)]
    print(b)
    

    印刷品 [2, 3, 1] [1, 2, 3, 1] . 和 Expression lists “表达式从左到右求值”

    1 回复  |  直到 3 年前
        1
  •  10
  •   user2357112    3 年前

    我怀疑这可能是个意外,尽管我更喜欢这种新的行为。

    这种新的行为是字节码的使用方式发生变化的结果 * 争论是有效的。变化就在眼前 changelog 在Python3.9下。0阿尔法3:

    bpo-39320

    • 构建\u元组\u解包
    • 构建\设置\解包

    • 列表到元组
    • 设置更新

    在Python3.7(我没有现成的3.8可供测试)上 f(*a, a.pop())

      1           0 LOAD_NAME                0 (f)
                  2 LOAD_NAME                1 (a)
                  4 LOAD_NAME                1 (a)
                  6 LOAD_METHOD              2 (pop)
                  8 CALL_METHOD              0
                 10 BUILD_TUPLE              1
                 12 BUILD_TUPLE_UNPACK_WITH_CALL     2
                 14 CALL_FUNCTION_EX         0
                 16 RETURN_VALUE
    

      1           0 LOAD_NAME                0 (f)
                  2 BUILD_LIST               0
                  4 LOAD_NAME                1 (a)
                  6 LIST_EXTEND              1
                  8 LOAD_NAME                1 (a)
                 10 LOAD_METHOD              2 (pop)
                 12 CALL_METHOD              0
                 14 LIST_APPEND              1
                 16 LIST_TO_TUPLE
                 18 CALL_FUNCTION_EX         0
                 20 RETURN_VALUE
    

    a (a.pop(),) 在堆栈上,然后将这两个iterable解压为一个元组。在新的字节码中,代码将列表推送到堆栈上,然后 l.extend(a) l.append(a.pop()) tuple(l) .

    这一变化的影响是改变了产品的包装 pop 打电话,但这似乎不是故意的。看着 ,其目的是简化字节码指令,而不是更改行为,bpo线程没有讨论行为更改。