在Python中定义函数接受(x,*args),但不接受(*args,x)。为什么?

在Python中定义函数接受(x,*args),但不接受(*args,x)。为什么?,python,python-2.7,Python,Python 2.7,我最近开始自学Python,并询问了有关定义函数的问题。我读到了函数中的*args和**args可能性,并决定试用它们。我试图通过使此函数处于空闲状态来制作一个非常简单的计算器: def test(*args, tool): total = 0 if(tool == '+' or tool == 'plus'): for a in args: total += a return total 但是,当我通过第一行时,Pyth

我最近开始自学Python,并询问了有关定义函数的问题。我读到了函数中的
*args
**args
可能性,并决定试用它们。我试图通过使此函数处于空闲状态来制作一个非常简单的计算器:

def test(*args, tool):
    total = 0
    if(tool == '+' or tool == 'plus'):
        for a in args:
            total += a
        return total
但是,当我通过第一行时,Python向我抛出了以下错误:

SyntaxError: invalid syntax
起初,我不知道我做错了什么,所以我尝试将它们都
type()
并意识到*args是一个元组,**args是一个字典。因此,我理解了当Python试图将字符串转换为元组,然后查找代码的
工具部分时,Python会多么困惑

但是,当我打开*args和tool:
def测试(tool,*args)
时,我根本没有遇到任何错误,代码按预期运行(奇怪的是,根本没有工具参数)。然而,当我试图以这种方式调用函数:
test(4,2,3,'tool')
时,它再次向我抛出了一个错误,抱怨它无法将int和string相加


发生了什么?

*args
必须位于函数调用的末尾。这是因为如果在
*args
之后有参数,Python无法知道
*args
何时结束,其余参数何时开始。如果在开始时有一组参数,那么
*args
,它知道在函数结束时停止

Python是一种解释语言,因此它将从左到右读取函数,并在执行过程中分配变量。采取以下行动:

def foo(bar, *args):
    print("Hello, world!", bar, args)
如果我传入
foo(3,4,5,6)
Python说,“好的,我们将
bar
设置为3。然后,剩下的参数进入
args
。这就是
(4,5,6)

现在,让论点反过来:

def foo(*args, bar):
    print("Hello, world!", bar, args)
对于相同的参数,Python会说,“其余的参数可以放在
参数中。这就是
(3,4,5,6)
。等等,
条呢?
?我们什么都没有了!”因此它抛出了一个错误


使用函数
test
,如果要将
*args
相加,则不能输入三个数字和一个字符串。您必须首先传入
工具,然后传入数字。

这只是因为解释器(或其他语言的编译器)的缘故。定义函数时,解释器会查找参数,然后是额外参数,然后是关键字参数;为了正确解释:

在这种情况下,解释器将只找到一个参数:

def (myArg): 
在这种情况下,解释器将找到一个参数和“剩余”参数,因此它知道如何映射第一个参数和其他参数

def (myArg, *args):
但在这种情况下,解释器会查找参数的
列表
,因此它会将所有参数都打包到args中;那么myArg会怎么样

def(*args, myArg): 

没有更多的参数,因为它已经将所有参数打包到args中,这只是因为解释器不知道args何时结束。

因为您不知道函数定义中有多少元素*args
*args
,这意味着“将其余参数放入列表”。它不支持“将其余的参数放入一个列表中,除了下一个单独声明的参数”。是的,我明白了。但是为什么def
(工具,*args)
可以工作呢?是因为它首先查找tool参数,然后查找*args参数吗?它是否绕过了tool参数而直接转到*args参数?还有,为什么我的函数工作起来就像工具等于+或+一样,即使我根本没有输入它?