1

I get the following error when I run the piece of code below. I can clearly print the value of *strs on screen, which appears as string. But, when I do type(*strs), it throws TypeError: type.__new__() argument 2 must be tuple, not str. Can someone explain this behaviour?

strs = ["flower","flood","flight"]
print(*strs)
print(type(strs))
print(type(*strs))

Output:

Traceback (most recent call last):
print(type(*strs))
TypeError: type.__new__() argument 2 must be tuple, not str
flower flood flight
<class 'list'>
Process finished with exit code 1
Ted Klein Bergman
  • 9,146
  • 4
  • 29
  • 50
Mahantesh
  • 53
  • 7
  • 1
    Does this answer your question? [What does the star operator mean, in a function call?](https://stackoverflow.com/questions/2921847/what-does-the-star-operator-mean-in-a-function-call) – Mad Physicist Feb 14 '21 at 05:20
  • Please add a plain python tag – Mad Physicist Feb 14 '21 at 05:20
  • 1
    His question was a little more involved than that. Specifically, he wanted an explanation as to the meaning of "type.__new__() argument 2 must be tuple, not str", and why his code caused that specific error. He wasn't asking what the star means. – user10637953 Feb 14 '21 at 05:25

1 Answers1

3

The asterix operator in '*strs' unpacks the iterms in 'strs', which is a series of three strings. Your code ran into trouble when it tried to send those strings to the type() command, where type() was initialized by its __ new__() magic method.

type() has two forms:

1.) type(object) where the 'object' is an instance of some class.

2.) type(name, bases, dictionary) where 'bases' is a tuple that itemizes base classes, and a dictionary that contains definitions of base classes.

In your code, the use of the unpacking operation, *strs, resulted in type() being sent three arguments, so it was expecting a name, a tuple, and a dictionary. What it, and then __ new()__ got was three strings: A name (it received 'flower'), then another string, "flood", where it wanted a tuple. Here python threw the error and never made it to the third string, 'flight'.

We can duplicate the error with:

 print(type("a","b","c"))

We can also see that either one or three (but not two) arguments were expected, with:

 print(type("a","b"))

while the following command works just fine:

print(type("a"))

If you want to see the type of each member of *strs, first let it unpack to a list, then iterate through that list, printing the type of each member as you go.

 mylist = [*strs]
 for elm in mylist:
      print(type(elm))

Does this answer the question of what caused that behavior and the error?

user10637953
  • 370
  • 1
  • 10