【问题标题】:How to understand variable-length argument in python function?如何理解python函数中的变长参数?
【发布时间】:2014-08-03 07:05:34
【问题描述】:

我想编写自己的 sum 函数来获取可变长度参数的总和。

def myadd(*tuple):
    sum=0
    for element in tuple:
        sum=sum+element
    return(sum)

调用方法一:

myadd(*(1,2,3,4))

这是最正式的函数调用方式,这里没问题。

调用方法二:

myadd(1,2,3,4)

也可以得到结果,为什么?

调用方法3:

myadd((1,2,3,4))

错误类型错误:+ 的不支持的操作数类型:'int' 和 'tuple'。

在我看来,调用2和调用3不能被python接受,参数位置没有*运算符?你能告诉我对python函数的操作原理吗?

【问题讨论】:

  • 你期望0 + (1, 2,3) 是什么?
  • 显而易见的问题是:内置的 sum 函数有什么问题?
  • 附带说明,你真的不应该调用你的参数tuple,因为这隐藏了tuple类型/构造函数的名称。

标签: python


【解决方案1】:

您混淆了可变参数参数和参数解包。对于初学者来说这是一个常见的错误,因为它们都使用相同的 * 语法,而且它们并非完全不相关……但它们的相关性并不像您想象的那么密切。


这两个调用做的事情完全相同:

myadd(*(1,2,3,4))
myadd(1, 2, 3, 4)

* 在这里的意思是“获取以下可迭代对象,并将其解压缩成一堆单独的参数。

无论您调用的函数是定义为f(*args)f(a, b, c, d) 还是f(a, b, *args),都没有关系,您向它传递了4 个参数。

这意味着方法 1 不是“调用函数的最正式方式”;实际上,它只是方法2的混淆版本。


另一方面,这并没有做同样的事情:

myadd((1, 2, 3, 4))

传递一个参数,恰好是一个元组。


所以,你的函数是这样定义的:

def myadd(*tuple):

这意味着无论它传递什么参数,不管它们是如何传递的(除了关键字参数,但我们暂时忽略它),它们将被扔进一个名为tuple 的列表中。那么,让我们看看你的三个案例。

在第一种情况下,您传递了 4 个参数,它们都是整数。所以,tuple 得到一个包含 4 个整数的列表。当您遍历该列表时,每个成员都是一个整数,因此您可以毫无问题地将它们相加。

在第二种情况下——同样,完全相同——你传递了 4 个整数,所以tuple 得到一个包含 4 个整数的列表。

在第三种情况下,您传递了 1 个参数,它是一个元组,因此 tuple 得到一个包含 1 个元组的列表。当您遍历该列表时,每个成员都是一个元组,您不能将其添加到数字中。


有关更多详细信息,请参阅 Arguments and parameters,其中包含指向文档中所有有用位置的链接,并希望是可读的概述。

【讨论】:

    【解决方案2】:

    您将整个元组作为一个参数传递,并且不能将元组添加到数字中。如果要将所有元组元素作为单独的参数传递,请使用 * 运算符:

    myadd(*x)
    

    【讨论】:

    • 我差不多明白了,函数是对的,调用方法不对。myadd(*(1,2,3)) 没问题。
    • 我知道 myadd(*(1,2,3,4)) 可以得到结果,为什么 myadd(1,2,3,4) 也可以得到结果?不是*的形式tuple ?这里没有*运算符,能多讲讲python中的函数原理吗?
    • @it_is_a_literature 阅读教程和/或手册怎么样?这是非常基本的东西。
    【解决方案3】:
    def myadd(x):                                
        sum=0                                    
        for element in x:                        
            sum=sum+element                      
        return(sum)                              
    
    x=(1,2,3)                                    
    print myadd(x) 
    

    输出

    6
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-01
      • 2010-09-07
      • 1970-01-01
      • 1970-01-01
      • 2021-10-21
      • 2014-05-04
      • 2018-08-01
      相关资源
      最近更新 更多