【问题标题】:What is the difference between the following two statements?以下两种说法有什么区别?
【发布时间】:2016-06-03 07:15:27
【问题描述】:
x = func(*(xa,) + args)
y = func(*((xc,) + args)) 

其中args是一个数组,函数定义是:

def func(lamb, data):
    # statements

我了解了*args,但我找不到这些行之间的确切区别。

【问题讨论】:

  • 一组额外的括号。就是这样,执行没有区别,字节码是一样的:dis.dis("func(*(xa,) + args)")给出的操作和dis.dis("func(*((xc,) + args))")完全一样
  • 第一个使用xa,第二个使用xc;)
  • 如果你试图调用的函数有两个参数并且你想传递两个参数,你为什么要使用*args 机制呢?你不想做func(xa, args)吗?
  • 我对 Python 还是很陌生。我不是在写,只是想了解一个源代码@TadhgMcDonald-Jensen

标签: python


【解决方案1】:

唯一的区别是额外的一组括号,一个使用xa,而另一个使用xc,但即使这样也没有太大区别to the byte code,看看:

# python 2 needs to use dis.dis(compile("func(*(xa,)+args)","","eval"))
# to get same result, see http://stackoverflow.com/questions/12673074/how-should-i-understand-the-output-of-dis-dis
>>> dis.dis("func(*(xa,)+args)")
  1           0 LOAD_NAME                0 (func)
              3 LOAD_NAME                1 (xa)
              6 BUILD_TUPLE              1
              9 LOAD_NAME                2 (args)
             12 BINARY_ADD
             13 CALL_FUNCTION_VAR        0 (0 positional, 0 keyword pair)
             16 RETURN_VALUE
>>> dis.dis("func(*((xc,)+args))")
  1           0 LOAD_NAME                0 (func)
              3 LOAD_NAME                1 (xc)
              6 BUILD_TUPLE              1
              9 LOAD_NAME                2 (args)
             12 BINARY_ADD
             13 CALL_FUNCTION_VAR        0 (0 positional, 0 keyword pair)
             16 RETURN_VALUE

这是precedence 的简单问题,添加优先于* 解包(CALL_FUNCTION_VAR 是使用的确切字节码),因此添加括号不会改变任何内容,就像这里一样:

3 * 5 + 1

乘法将首先发生,所以在它周围添加括号:

(3 * 5) + 1

不会改变将要发生的事情。


还请注意,您不必在解包参数时将元组添加在一起,您可以很容易地这样做:

func(xa, *args)

无需将元组添加在一起即可完成相同的结果(当args 不是元组时,这将起作用,因为您的版本会引发 TypeError)

【讨论】:

    猜你喜欢
    • 2014-07-16
    • 2020-01-22
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    相关资源
    最近更新 更多