Python 替换位置参数-使用或不使用元组参数调用函数

Python 替换位置参数-使用或不使用元组参数调用函数,python,arguments,tuples,Python,Arguments,Tuples,当我运行此代码时: def withPositionalArgs(*args): print args, type(args) def withTupleAsArgument(tupleArg): print tupleArg, type(tupleArg) a=1 b=2 c=[10,20] print withPositionalArgs(a,b,c) print withTupleAsArgument(tuple([a,b,c])) (1,2[10,20]) 没有一

当我运行此代码时:

def withPositionalArgs(*args):
    print args, type(args)

def withTupleAsArgument(tupleArg):
    print tupleArg, type(tupleArg)

a=1
b=2
c=[10,20]

print withPositionalArgs(a,b,c)
print withTupleAsArgument(tuple([a,b,c]))
(1,2[10,20])
没有一个
(1, 2, [10, 20]) 
没有一个
疑问:


由于位置参数作为元组传递,这两个函数调用在技术上有什么区别吗?如果我在调用时已经可以创建一个元组,那么是否需要使用位置参数?没有它们,事情也可以顺利进行,不是吗?或者有什么我没有理解或忽略的吗?

没有,两者之间没有区别。在第一个示例中,您的参数以一个元组结束,在第二个示例中,您将发送一个元组。

您需要问问自己,您的函数将如何使用。将参数视为一组不相关的值是否更自然,在这种情况下,位置参数更有意义。或者这些值形成一个相关的组,在这种情况下,元组更有意义

你还需要考虑如何使用你的函数。假设你有一个函数 返回值的元组:

(1, 2, [10, 20]) <type 'tuple'>
None
(1, 2, [10, 20]) <type 'tuple'>
None
您需要编写一个函数
bar
,其参数是
foo
返回的值。你的两个选择是

def foo():
    return 1,2,3
以下是使用
foo
的返回值直接作为参数调用这两个函数的几种方法:

>bar1(foo())#接收一个元组值参数
(1, 2, 3)
>>>bar1(*foo())#接收3个整数参数
1.
>>>bar2(foo())#接收单元组值参数
1.
>>>bar2(*foo())#接收3个参数,但预期只有1个!
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:bar2()正好接受1个参数(给定3个)

因此,在
bar1
bar2
之间的选择实际上取决于您希望如何使用它。

最大的区别在于位置参数“*args”方式允许一个人在运行时调用一个他不知道参数数量的函数,并且仍然具有与“普通”相同的函数工作方式函数用于其他调用

当一个人将一个函数作为参数发送给另一段代码,或者编写一个函数包装器来接收“N”个参数并将这些“N”个参数传递给原始函数,而不关心它们时,最常用(但不是单独使用)

它是使用Python编写动态代码如此伟大的一个重要部分

例如:

>>> bar1(foo())  # Receives a single tuple-valued argument
(1, 2, 3)
>>> bar1(*foo()) # Receives 3 integer arguments
1
>>> bar2(foo())  # Receives a single tuple-valued argument
1
>>> bar2(*foo()) # Receives 3 arguments, but only expected 1!
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: bar2() takes exactly 1 argument (3 given)
此代码段创建了一个decorator,用于打印传递给函数的arguemtn,但仍然可以使用仅使用位置参数调用的任何函数。(添加关键字参数将使其适用于任何可调用的函数)

但是,任何使用原始版本的
MySun
的代码都可以不加更改地继续使用。
如果使用普通元组将参数传递给装饰器,则必须相应地修改调用代码。

Deos这意味着如果我在调用时已经可以创建元组,就不需要使用位置参数了?
>>> bar1(foo())  # Receives a single tuple-valued argument
(1, 2, 3)
>>> bar1(*foo()) # Receives 3 integer arguments
1
>>> bar2(foo())  # Receives a single tuple-valued argument
1
>>> bar2(*foo()) # Receives 3 arguments, but only expected 1!
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: bar2() takes exactly 1 argument (3 given)
def MySum(a,b):
    return a + b

def logger(func):
   def wrapper(*args):
       print args
       return func(*args)
   return wrapper

MySum = logger(MySum)