How best to check for existance of an attribute?

Alex Martelli aleax at aleax.it
Fri Dec 28 11:14:32 EST 2001


"Greg Krohn" <infinitystwin.SPAM at IS.BAD.yahoo.com> wrote in message
news:3c28f373$0$79558$6e49188b at news.goldengate.net...
> "Roy Smith" <roy at panix.com> wrote in message
> news:roy-DD8C6B.16193025122001 at news1.panix.com...
> > I've got a function which augments an object passed to it by adding a
new
> > attribute.  Something like this:
> >
> > def addStuff (obj):
> >    obj.newAttr = "stuff"
> >
> > I want it to be an error to call addStuff() more than once for a given
    ...
> This is what I would do:
>
> def addStuff (obj):
>     if hasattr(obj, 'stuff'):
>         raise MultipleCallError
>     else:
>         setattr(obj, 'stuff', None)

class Tricky:
    newAttr = "aDefault"

dick = Tricky()


Now, addStuff(dick) would fail.  Is this what the OP wants?  Maybe (some
of his examples "ways to do it" would behave the same way) but it doesn't
quite sound right given the specs of "calling more than once".

The point is just that hasattr also finds the attributes in the object's
class.  If you only want attributes _in the object itself_, NOT ones the
object gets from its class, it's a bit trickier, depending on what exact
range of cases you want to handle (e.g., can obj be assumed to have a
__class__ attribute, as in Python 2.2, or do you have to check for that,
too?).  Assuming only objects with a __class__ are of interest (or that
only Python 2.2 and up is of interest), then, maybe, a sentinel-like
approach might be simplest:

def addStuff(obj):
    class Unique: pass
    inclass = getattr(obj.__class__, 'stuff', Unique())
    inobject = getattr(obj, 'stuff', inclass)

    if inobject is inclass:
        obj.newAttr = "stuff"
    else:
        raise MultipleCallError, obj

This might still fail, depending on interning of "stuff",
for:
    addStuff(obj.__class__)
    addStuff(obj)
where the second call would be wrongly diagnosed as multiple.  Is
there a need to support this usage?

Testing if obj.__dict__.has_key('stuff') might often help,
but would still fail in 2.2 if obj didn't have a __dict__.
Is THIS a problem?

Only the OP knows...


Alex






More information about the Python-list mailing list