hasattr() vs try-except block to deal with non-existent attributes

前端 未结 12 2391
庸人自扰
庸人自扰 2020-11-30 23:29
if hasattr(obj, \'attribute\'):
    # do somthing

vs

try:
    # access obj.attribute
except AttributeError, e:
    # deal with Attr         


        
12条回答
  •  难免孤独
    2020-11-30 23:59

    I almost always use hasattr: it's the correct choice for most cases.

    The problematic case is when a class overrides __getattr__: hasattr will catch all exceptions instead of catching just AttributeError like you expect. In other words, the code below will print b: False even though it would be more appropriate to see a ValueError exception:

    class X(object):
        def __getattr__(self, attr):
            if attr == 'a':
                return 123
            if attr == 'b':
                raise ValueError('important error from your database')
            raise AttributeError
    
    x = X()
    print 'a:', hasattr(x, 'a')
    print 'b:', hasattr(x, 'b')
    print 'c:', hasattr(x, 'c')
    

    The important error has thus disappeared. This has been fixed in Python 3.2 (issue9666) where hasattr now only catches AttributeError.

    An easy workaround is to write a utility function like this:

    _notset = object()
    
    def safehasattr(thing, attr):
        return getattr(thing, attr, _notset) is not _notset
    

    This let's getattr deal with the situation and it can then raise the appropriate exception.

提交回复
热议问题