2012-09-08 63 views
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 

疑惑:

由于位置参数作为一个元组过去了,有techcnially任何这两个函数调用之间的区别?如果在我打电话的时候我已经可以创建一个元组了,是否需要使用Positional参数?没有他们的东西也可以工作,不是吗?或者有什么我没有理解或忽视的东西?

回答

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] 

这里是直接为你的论点(S)的一些方法,你可以调用每个两种功能,采用的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真的取决于您如何使用它。

1

没有,有两者之间没有什么区别。在第一个参数中,你的参数最后成为一个元组,第二个元组发送了一个元组。

+0

Deos,这意味着如果我可以在我打电话的时候创建一个元组,那么不需要使用Positional参数吗? – GodMan

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原始版本可以继续任何代码就不变。 如果使用普通元组将参数传递给装饰器,调用代码将不得不相应地修改。