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)