In python you can do this:
def myFunction():
return "String", 5.5, True, 11
val1, val2, val3, val4 = myFunction()
I argue that this is a function which returns 4 values, however my python instructor says I am wrong and that this only returns one tuple.
Personally I think this is a distinction without a difference because there is no indication that these four values are converted into a tuple and then deconstructed as 4 values. I am unaware of how this is any different than the same type of construct in languages like JavaScript.
Am I right?
CodePudding user response:
I'll take a stab at this, since I think the issue here is a lack of defining terms properly. To be completely pedantic about it, the correct answer to the question as worded is "zero". Python doesn't return a value; it returns an object, and an object is not the same thing as a value. Going back to basics on this one:
https://docs.python.org/3/reference/datamodel.html#objects-values-and-types
Objects are Python’s abstraction for data. All data in a Python program is represented by objects or by relations between objects.
also:
Every object has an identity, a type and a value.
A value, as defined above, is something different than an object. Functions return objects and not values, so the answer to the question (as asked, if taken to literal extremes) is zero. If the question had been, "How many objects are returned to the caller by this function?" then the answer would be one. This is why defining terms is important, and why vague questions generate multiple (potentially correct) answers. In another sense, the correct answer to the question would be five, because there's five things one might think of as "values" coming back from this function. There's a tuple, and there's the four items inside the tuple. In still another sense, the answer is four (as you've said) because the code flat out says return and then has four values afterwards.
So really, you're both right, and you're both wrong, but only because the question isn't sufficiently clear as to what it wants to know. The instructor is likely trying to put forth the idea that Python returns single objects, which may contain multiple other objects. This is important to know, because it contributes to Python's flexibility when passing data around. I'm not so sure the way the instructor worded it is achieving that goal, but I'm also not present in the class, so it's tough to say. Ideally, instruction should cover neurodiverse ways of understanding, but I'll save that soapbox for a different discussion.
Let's distill it like this in hopes of providing a clear summary. Python doesn't return values, it returns objects. To that end, a function can only return one object. That object can contain multiple values, or even refer to other objects, so while your function can pass back multiple values to the caller, it must do so inside of a single object. "Objects" are the internal unit of data inside of Python, and are distinctly different from the "value" contained in the object, so it's a good practice in Python to always keep in mind the distinction between the two and how they're used, regardless of how the question is worded.
CodePudding user response:
Your instructor is correct.
https://docs.python.org/3/reference/datamodel.html#objects-values-and-types
Tuples
The items of a tuple are arbitrary Python objects. Tuples of two or more items are formed by comma-separated lists of expressions. A tuple of one item (a ‘singleton’) can be formed by affixing a comma to an expression (an expression by itself does not create a tuple, since parentheses must be usable for grouping of expressions). An empty tuple can be formed by an empty pair of parentheses.
Applied to your example:
foo = "String", 5.5, True, 11
assert isinstance(foo, tuple)
So you're clearly returning a single object.
Here's how the assignment expression is specified when there are multiple targets (variables on the left hand side):
https://docs.python.org/3/reference/simple_stmts.html#assignment-statements
Assignment of an object to a target list, optionally enclosed in parentheses or square brackets, is recursively defined as follows.
If the target list is a single target with no trailing comma, optionally in parentheses, the object is assigned to that target.
Else: The object must be an iterable with the same number of items as there are targets in the target list, and the items are assigned, from left to right, to the corresponding targets.
(All emphasis mine)