Checking if an Object Has Necessary Attributes
Credit: Alex Martelli
Problem
You need to check if an object has certain necessary attributes, before performing state-altering operations, but you want to avoid type-testing because you know it reduces polymorphism.
Solution
In Python, you normally try whatever operations you need to perform. For example, here’s the simplest, no-checks code for manipulations of a list:
def munge1(alist):
alist.append(23)
alist.extend(range(5))
alist.append(42)
alist[4] = alist[3]
alist.extend(range(2))While this is usually adequate, there may be occasional problems. For
example, if the alist object has an
append method but not an extend
method, the munge1 function will partially alter
alist before an exception is raised. Such partial
alterations are generally not cleanly undoable, and, depending on
your application, they can be quite a bother.
To avoid partial alteration, you might want to check the type. A naive Look Before You Leap (LBYL) approach looks safer, but it has a serious defect: it loses polymorphism. The worst approach of all is checking for equality of types:
def munge2(alist):
if type(alist)==type([]):
munge1(alist)
else: raise TypeError, "expected list, got %s"%type(alist)A better, but still unfavorable, approach (which at least works for
list subclasses in 2.2) is using
isinstance:
def munge3(alist):
if isinstance(alist, type[]):
munge1(alist)
else: raise TypeError, "expected list, got %s"%type(alist)The proper solution is accurate LBYL, ...