isinstance()

dn PythonList at DancesWithMice.info
Fri Aug 4 19:35:03 EDT 2023


On 05/08/2023 11.18, Chris Angelico via Python-list wrote:
> On Sat, 5 Aug 2023 at 09:08, dn via Python-list <python-list at python.org> wrote:
>>
>> On 03/08/2023 11.38, Jon Ribbens via Python-list wrote:
>>> On 2023-08-02, dn <PythonList at DancesWithMice.info> wrote:
>>>> Can you please explain why a multi-part second-argument must be a tuple
>>>> and not any other form of collection-type?
>>>
>>> The following comment may hold a clue:
>>>
>>>       if (PyTuple_Check(cls)) {
>>>           /* Not a general sequence -- that opens up the road to
>>>              recursion and stack overflow. */
>>>
>>> https://github.com/python/cpython/blob/main/Objects/abstract.c#L2684
>>>
>>> Plus an almost total lack of demand for change I should think.
>>
>> Thanks for the reference!
>>
>>
>> Am not proposing a change (have learned 'the rule' and accepted
>> life-as-it-is), but was curious about the restriction: why not any
>> (reasonable sequence)?
> 
> There are quite a few places where the only option is a tuple.
> 
>>>> "spam".startswith(["sp", "h"])
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> TypeError: startswith first arg must be str or a tuple of str, not list
>>>> try: 1/0
> ... except [ValueError, IndexError]: pass
> ...
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> ZeroDivisionError: division by zero
> 
> During handling of the above exception, another exception occurred:
> 
> Traceback (most recent call last):
>    File "<stdin>", line 2, in <module>
> TypeError: catching classes that do not inherit from BaseException is
> not allowed
> 
> It simplifies a lot of checks. Either it's a tuple or it's a single
> thing. A *lot* of values are iterable, but only tuples are tuples.
> 
> As the C comment notes, this also means you don't have to worry about
> recursion; otherwise, even core language features like exception
> handling would have to iterate over a thing while ensuring that they
> don't get stuck in self-referential objects. (Incidentally, it seems
> that exception handling doesn't bother with recursion *at all*, and
> won't catch "(a, (b, c))" - but even if recursion is handled, it can't
> go infinite, short of some serious messing around in ctypes or the C
> API.)
Yes. Thanks Chris!

The idea that such 'lists' be immutable (even, hashable), and therefore 
a tuple, makes a certain amount of sense, and @Cameron mentioned 
'frugality'.


My limitation is thinking only at the Python level (which as @Jon 
pointed-out, is only part of the story).

Faced with a situation where an argument may be a scalar-value or an 
iterable, I'll presume the latter, eg throw it straight into a for-loop. 
If that fails (because the argument is a scalar), use try-except to 
re-route the logic. Alternately, in an OOP situation, utilise 
polymorphism so that the 'scalar' and 'iterable' instances both include 
the appropriate method[name]. Accordingly, as long as the argument is an 
iterable (includes an __iter__() method), the actual type/class is 
more-or-less irrelevant.


However, as observed earlier - and with these additions, having learned 
the 'rule', ie use a tuple; the brain is still pondering, but have 
shrugged-shoulders and carried-on regardless...

-- 
-- 
Regards,
=dn


More information about the Python-list mailing list