Я почти всегда использую hasattr
: это правильный выбор для большинства случаев.
Проблематичным является случай, когда класс переопределяет __getattr__
: hasattr
будет перехватывать все исключения вместо того, чтобы просто перехватывать AttributeError
, как вы ожидаете. Другими словами, приведенный ниже код будет печатать b: False
, хотя было бы более уместно увидеть исключение ValueError
:
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')
Важная ошибка, таким образом, исчезла. Это было исправлено в Python 3.2 ( issue9666 ), где hasattr
теперь только ловит AttributeError
.
Простой обходной путь - написать служебную функцию, подобную этой:
_notset = object()
def safehasattr(thing, attr):
return getattr(thing, attr, _notset) is not _notset
Это давайте getattr
разберемся с ситуацией и затем можем вызвать соответствующее исключение.