0
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]) <type 'tuple'>
None
(1, 2, [10, 20]) <type 'tuple'>
None

疑点:

由于位置参数作为元组传递,这两个函数调用在技术上是否有区别?如果我在打电话时已经可以制作一个元组,是否需要使用位置参数?没有它们也可以工作,不是吗?或者有什么我没有理解或忽略的东西?

4

3 回答 3

1

不,两者没有区别。在第一个中,您的 args 最终出现在一个元组中,第二个您正在发送一个元组。

于 2012-09-08T13:43:33.920 回答
1

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

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

def foo():
    return 1,2,3

并且您想编写一个函数bar,其参数是foo. 你的两个选择是

# Take a sequence of values and store them in a tuple called args
def bar1(*args):
    print args[0]

# Take a tuple of values and store it in t
def bar2(t):
    print t[0]

这里有一些你可以调用这两个函数的方法,foo直接使用返回值作为你的参数:

>>> 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)

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

于 2012-09-08T14:38:19.283 回答
0

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

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

它是在 Python 中编写动态代码如此出色的重要组成部分。

例如:

def MySum(a,b):
    return a + b

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

MySum = logger(MySum)

这个代码片段创建了一个装饰器来打印出传递给函数的arguemtns,它仍然可以与任何仅使用位置参数调用的函数一起工作。(添加关键字参数将使其对任何可调用函数都有效)。

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

于 2012-09-08T14:41:40.480 回答