Reputation:
What is the difference and use cases of typing.Collection
?
E.g.:
from typing import Collection, Iterable
foo: Collection[int] = (1, 2)
bar: Iterable[int] = (1, 2)
spam: tuple[int] = (1, 2)
As for me, all looks the same and I do not understand why not to use always list
, tuple
, etc. as type hints.
Upvotes: 18
Views: 11234
Reputation: 45750
It depends on what the capabilities of the object you need are. The general advice I've followed regarding type specification is
Specify the most general type when taking input, and the most specific type when giving output
If you don't need a Tuple
specifically, don't specify a Tuple
. Unless you absolutely need a tuple, you'll make the caller's life more difficult by specifying Tuple
because you'll force them to either ignore your hints, or convert between collections if they currently have, for example, a list instead of a tuple.
Here's an example:
def func(tup: ???):
for n in tup:
pass
The only thing tup
is used for is iteration. That means, following the above advice, you should fill in ???
with Iterable
. That way, the caller can give a tuple, list, or even a custom type of theirs. It doesn't matter since your code doesn't care about the type; only that the object is iterable.
Contrast that with something like:
def func(lst: ???):
lst.append(1)
lst[2] = 5
This requires more specific functionality; but is still more general than a list
. append
and __setitem__
are a part of the MutableSequence
ABC, so I'd specify that.
I rarely specify concrete collection types when type hinting input. The vast majority of the time, specifying the narrow set of capabilities that you require of the object is easy. Also for tuples specifically, I only specify Tuple
in the cases where I want the user to input a sequence of pairs or something similar. Say I have a function that accepts an iterable of pairs of numbers. I'd type hint that input as:
Iterable[Tuple[int, int]]
I use Tuple
(or tuple
now) because the size of the pairs should be fixed at exactly two. I could accept a list of numbers, but then I don't have any size "guarantees". If I require the elements to have exactly a size of two, specifying Tuple
is the cleanest way to achieve that.
Reference this table, and pick the type that best represents the actions that you want to carry out on the object.
Upvotes: 31