Is 'isinstance()' the right thing?

Alex Martelli aleax at aleax.it
Thu May 9 07:56:10 EDT 2002


Ralf Juengling wrote:
        ...
>> The "Pythonic" way of argument checking is to simply use it and catch
>> the exceptions that will be thrown if it doesn't behave as planned.
> 
> Hm, you might risk to destroy something this way (i.e. when an exception
> occurs to late).

I have observed this, in about 5% to 10% of cases -- when I need a function
to be somewhat "atomic", performing on an object argument either 'all' of a
set of state alterations, or none -- whatever the type of the actual
argument.  90%+ of the time, of course, such "failsafe" behavior is not
needed -- calling the function with a weird argument is a programming error
and it doesn't matter if some state is altered before throwing an
exception.  However, it's exactly for that small but important remaining
slice of cases, that I wrote the "accurate LBYL" Cookbook recipe I pointed
you to earlier (on ActiveState's Python Cookbook site).


>> Depending on what you want, some of the is... functions in the operator
>> module might be to your liking.
> 
> Thanks, I wasn't aware of these (looked for them in the type module).
> *BUT*, these (eg. isSequenceType) work only for C extension types, right?

Not quite, but what it checks if is the object's type implements the
C_API level "sequence" interface -- which the BDFL is musing about
deprecating anyway, since, with slice accesses now best obtained through
item methods, and iterators as a separate concept, the "sequence" stuff is 
just duplicating mapping and numerical stuff.  So, I wouldn't rely on it.

PEP 246 would allow MORE than just checking if an object, exactly as it
is, currently implements an interface: it would allow the object itself
or a third-party adapter to interpose an Adapter that lets you use the
object "just as if" it implemented the interface.  All the benefits of
COM's QueryInterface approach (vastly superior to C++'s dynamic_cast,
since it lets the object build needed parts of itself JIT, on-the-fly)
PLUS those of COM's IServiceProvider (since no identity constraint on
the returned object).  Of course if for some weird reason you needed to
check if an Adapter is in use, that would be easy too:

        conformant = adapt(argument, requiredProtocol)
        if conformant is argument:
                " no adaptation, work on the original object "
        else:
                " adaptation occurred, whatever you want to do about it"

<sigh>.  So far I think I managed to explain it well enough to get the
BDFL to agree this would be good IF Python had 'interfaces' as a concept
separate from types and classes, so that 'requiredProtocol' would have
to be an 'interface'.  I just can't manage to explain why types or
classes would be just as good in the 'requiredProtocol' role as would
be 'interfaces', so there's no need to wait for the latter and 246
could just be allowed to go ahead now.  Oh well... one day I'll get some
inspiration for how to go about it...


Alex




More information about the Python-list mailing list