4

I cannot understand why isinstance function as second parameter need a tuple instead of some iterable?

isinstance(some_object, (some_class1, some_class2))

works fine, but

isinstance(some_object, [some_class1, some_class2])

raise a TypeError

3
  • 2
    this question might be helpful. Commented May 6, 2019 at 8:30
  • Tthe answer at the linked question gives a good start for the why. Everyone should read it before posting an answer here. Commented May 6, 2019 at 8:32
  • Than you Caleb! that help me to understand the reason. Commented May 6, 2019 at 8:45

5 Answers 5

3

The reason seems to be "allowing only tuples is enough, it's simpler, it avoids the danger of some corner cases, and it seemed neater to the BDFL" (i.e. Guido). (Kudos to @Caleb for posting the key link in the comments.)

Here is an excerpt from this email conversation with Guido van Rossum that specifically addresses the case of other iterables for the isinstance function. (Click on the link for the complete conversation.)

On Thu, Jan 2, 2014 at 1:37 PM, James Powell wrote:

This is driven by a real-world example wherein a large number of prefixes stored in a set, necessitating:

any('spam'.startswith(c) for c in prefixes)
# or
'spam'.startswith(tuple(prefixes))

Neither of these strikes me as bad. Also, depending on whether the set of prefixes itself changes dynamically, it may be best to lift the tuple() call out of the startswith() call.

...

However, .startswith doesn't seem to be the only example of this, and the other examples are free of the string/iterable ambiguity:

isinstance(x, {int, float})

But this is even less likely to have a dynamically generated argument.

And there could still be another ambiguity here: a metaclass could conceivably make its instances (i.e. classes) iterable.

Sign up to request clarification or add additional context in comments.

2 Comments

@Fanto If the answer was helpful, please accept it by clicking the checkmark below the voting buttons.
By the way, thanks to this question I learned that str.startswith() can take a tuple as its argument! :-) I would have never thought to check.
1

It is exacly as it should behave, according to the docs: https://docs.python.org/3/library/functions.html#isinstance

If classinfo is a tuple of type objects (or recursively, other such tuples), return true if object is an instance of any of the types. If classinfo is not a type or tuple of types and such tuples, a TypeError exception is raised.

2 Comments

That doesn't really answer why this is the case.
See the link posted by @Caleb: It is for an unrelated question, but it explains the reason that certain functions only accept tuples.
0

Because a string is also "some iterable". So you could write:

isinstance(some_object, 'foobar')

and it would check if some_object is an instance of f, o, b, a or r.

This wouldn't work obviously, so isinstance would need to check if the second argument is not a string. Since isinstance needs to do a type check, it might as well make sure the second argument is always a tuple.

Comments

0

Because this is the way the language was designed...

When you write code that can accept more that one type, it is easier to have fixed types that you can directly test than using duck typing. For example as strings are iterable, when you want to accept either a string of a sequence of strings you must first test for the string type.

Here I can imagine no strong reason for limiting to the tuple type, but no strong reason either to extend it to any sequence. You could try to propose it on the python-ideas list.

1 Comment

Please don't try to propose it on python-ideas! They've gone over that ground already, and decided against it.
-1

At a high level need a container type for isinstance checks, so you have tuples, lists, sets, and dicts for built-in containers. Most likely, they decided on tuple over a set because the expected use case for isinstance is a small number of types, and a tuple is faster to check for containment of than compared to a set.

Mutability really isn't a consideration. If they really needed immutability, they could have just re-wrapped the iterable into a tuple before processing.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.