Checking the type

Alex Martelli aleaxit at yahoo.com
Wed Mar 21 09:12:23 EST 2001


"Markus Reitz" <Markus_Reitz at yahoo.com> wrote in message
news:99a493$bhl$1 at sun.rhrk.uni-kl.de...
> Hi,
>
> is there a possibilty to check if a variable refers to an object of type
x?
> Does a typeof-command exist in Python:
>
>   if a typeof list:
>      #Commands only useable with list
>
> I read the Python Tutorial, but have not found a hint to this topic.

Yes,

    if type(a)==type([]):

will give you what you're asking for -- but, it's normally
*NOT* what you really want.  Why stop future client-code
from passing in an instance object that just _mimics_ a
list (rather than _being_ one), for example?

It's more Pythonic to just go ahead and treat a AS IF it
were a list -- and maybe, depending on context, catch and
handle the exceptions you'll get if a is not amenable to
such treatment.

Sometimes you can do the equivalent-checks once and for
all at the start, to avoid incorrectly doing SOME changes
on an object that doesn't support all you need, for
example...:

# simplest
def munge(alist):
    alist.append(23)
    alist.extend(range(5))
    alist.append(42)
    alist[4] = alist[3]
    alist.extend(range(2))

this is simple BUT if alist happens to be an object that
has an append method and LACKS an extend method, or the
ability to be indexed, then alist will be 'partially
modified' and THEN the AttributeError or TypeError will
be raised -- often an unpleasant situation!

Not to worry -- it's not too hard to remedy this:

# safer
def munge(alist):
    # first extract all bound-methods we'll need
    append = alist.append
    extend = alist.extend

    # then check operations such as indexing
    try: a[0]=a[0]
    except IndexError: pass    # empty alist's OK

    # and finally operate -- no exceptions expected
    append(23)
    extend(range(5))
    append(42)
    alist[4] = alist[3]
    extend(range(2))


This doesn't interfere with polymorphism (any
object supporting all needed operations with the
right semantics will do), and yet is safer than
the previous version _without_ being substantially
slower or more complicated (well, a little, I guess).
It's important to avoid overdoing the checks, but
the assert statement can come in handy for checks
we don't want to happen in production/optimized
code (e.g, one may add "assert callable(append)"
etc to the above example).

(Such versions of the look-before-you-leap idiom
is popular in C++ templates, to get compiler
errors that are clearer and earlier, but then,
I've often said that C++ templates and Python
functions show surprising parallels:-).


Alex






More information about the Python-list mailing list