【问题标题】:Replacing Positional arguments - calling a function with or without tuple arguments替换位置参数 - 调用带有或不带有元组参数的函数
【发布时间】:2012-09-02 02:41:00
【问题描述】:
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

疑问:

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

【问题讨论】:

    标签: python arguments tuples


    【解决方案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)
    

    所以bar1bar2 之间的选择实际上取决于您期望它的使用方式。

    【讨论】:

      【解决方案2】:

      不,两者之间没有区别。在第一个中,您的 args 最终成为一个元组,第二个您发送一个元组。

      【讨论】:

      • Deos 这意味着如果我在调用时已经可以创建一个元组,就不需要使用位置参数?
      【解决方案3】:

      最大的区别是位置参​​数“*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)
      

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-15
        • 2018-02-05
        • 2013-08-19
        相关资源
        最近更新 更多