I have a function like this one
def print_stuff(items):
if isinstance(items, (str, bytes)):
items = (items,)
for item in items:
print (item)
that can be called as follows:
In [37]: print_stuff(('a', 'b'))
a
b
In [38]: print_stuff('a')
a
I don't like doing isinstance (items, (str, bytes))
I would prefer to do isinstance(item, (collections.abc.MAGIC))
where MAGIC is a ABC of all the sequence objects that can contain other sequence objects such as
but not:
I am afraid this is impossible as tuple
and str
have the same 7 ABCs :(
In [49]: [v for k, v in vars(collections.abc).items()
...: if inspect.isclass(v) and issubclass(tuple, v) ]
Out[49]:
[collections.abc.Hashable,
collections.abc.Iterable,
collections.abc.Reversible,
collections.abc.Sized,
collections.abc.Container,
collections.abc.Collection,
collections.abc.Sequence]
In [50]: [v for k, v in vars(collections.abc).items()
...: if inspect.isclass(v) and issubclass(list, v) ]
Out[50]:
[collections.abc.Iterable,
collections.abc.Reversible,
collections.abc.Sized,
collections.abc.Container,
collections.abc.Collection,
collections.abc.Sequence,
collections.abc.MutableSequence]
In [51]: [v for k, v in vars(collections.abc).items()
...: if inspect.isclass(v) and issubclass(str, v) ]
Out[51]:
[collections.abc.Hashable,
collections.abc.Iterable,
collections.abc.Reversible,
collections.abc.Sized,
collections.abc.Container,
collections.abc.Collection,
collections.abc.Sequence]
Good question.
isinstance(x, str)
.bytes
and bytearray
can be distinguished using the collections.abc.ByteString
ABC.Of course, you could also define your own ABC which includes both str
and ByteString
, or even give it a __subclasshook__
that checks classes for a method such as capitalize
.