tuples as function arguments

自闭症网瘾萝莉.ら 提交于 2021-01-26 17:58:50

问题


a tuple in python (in a code block) is defined by the commas; the parentheses are not mandatory (in the cases below). so these three are all equivalent:

a, b = 1, 2
a, b = (1, 2)
(a, b) = 1, 2

if i define a function

def f(a, b):
    print(a, b)

calling it this way will work:

f(2, 3)

this will not:

f((2, 3))
# TypeError: f() missing 1 required positional argument: 'b'

how does python treat tuples differently when they are function arguments? here the parentheses are necessary (i understand why this is the case and i am happy python works this way!).

my question is: how does python treat tuples differently when they are function arguments.


回答1:


For convenience, Python constructs a temporary tuple as needed for an assignment statement. Thus, all three of your assignment statements are exactly the same once they reach data movement.

A function call is not an assignment statement; it's a reference mapping. Therefore, the semantics are different.

If you want Python to unpack your tuple into two separate arguments, use the * operator:

f(*(2, 3))



回答2:


A tuple behaves like an immutable list. The fact that you notate them with parentheses is perhaps confusing, but it's more or less a coincidence - a result of the fact that parentheses are used for grouping things together and reducing ambiguity otherwise.

When you call a function, you're not providing a tuple. You're providing arguments. A tuple can be an argument, but only one - it's just a variable of type tuple.

What you can do is expand a tuple (or a list) into a a series of arguments with this notation:

tup = (2, 3)
f(*tup)
# expand the tuple (2,3) into a series of arguments 2, 3

You can do that with dictionaries as well, except with ** instead of *:

my_dict = {"arg1": 1, "arg2": 2}
f(arg1=my_dict["arg1"], arg2=my_dict["arg2"])
f(**my_dict)   # these are equivalent

On the other hand, functions can take arbitrary numbers of arguments (similar to how other languages do for printf() calls). For example:

def g(*args):
    print("I got this many arguments:", len(args))

Here, if you do type(args), you get tuple, and if you do type(*args), you get an error. This is because, in function headers, the * does the exact opposite: it packs the arguments that were given to the function into a single tuple, so that you can work with them. Consider the following:

g(2, 3)  # 2 arguments, both integers
g((2, 3)) # 1 argument, a tuple
g(*(2, 3)) # 2 arguments, both integers

In short,

  • functions are built in such a way that they take an arbitrary number of arguments
  • The * and ** operators are able to unpack tuples/lists/dicts into arguments on one end, and pack them on the other end
  • individual tuples/lists/dicts are otherwise just individual variables.



回答3:


The thing is that parens are used for several different things in Python -- for calling functions, for making tuples (it's not just the commas that matter, see the empty tuple ()), for changing evaluation priority in expressions.

In cases where interpreting them is ambiguous (e.g. your example f(2, 3) could be either a function call with two arguments, or a function call with one argument that is a tuple) the language has to make a choice.

If the Python parser was implemented so that it parsed this as a tuple, it would be impossible to have functions with more than one argument. If the Python parser was implemented so that it parsed this as two arguments, it's impossible to pass a literal tuple without the parens.

Clearly the first is a much bigger limitation, so the second was chosen.

Another example is with tuples with one element -- is (1+2) an expression yielding the number 3, or a tuple with one element, 3? Here if it was the second, then it would be impossible to use parens for expressing priority in an expression ((3+4)*5 vs 3+(4*5)). So it was decided to require the comma after the first element for 1-element tuples ((3,)).



来源:https://stackoverflow.com/questions/56498558/tuples-as-function-arguments

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!