Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Самый первый вопрос: стоит ли шкурка вычинки? Стоило ли проделывать такое количество работы ради получения очевидных результатов? Помоему достаточно иметь общее представление о затратах на каждый из методов.
__dict__ — поиск значения в ассоциативном массиве. Что может быть быстрее? Только прямое обращение к атрибуту, если он есть...
__dict__?hasattr — реализован через getattr и исключения. Тогда очевидно, что по времени затраты будут примерно такие же как и на отдельную проверку getattr с отловом исключения (при наличие атрибута — быстро, при отсутствие — медленно).
hasattr был реализован как getattr с проверкой исключения, то тогда тесты exc_getattr и hasattr показали бы одинаковые результаты — а это не так. Скорее, hasattr проходит по всем __dict__-ам, начиная от экземпляра класса и заканчивая самым «глубоким» объектом класса, осуществляя lookup во всех классах. Возможно, я ошибаюсь — нужно смотреть в исходники Python.dir — достаточно оценить время выполнения этой функции и сравнить с поиском в ассоциативном массиве.
dir() используется именно с этой целью :)Кстати, а как на счет getattr(obj, attr_name, None)? Имхо, если атрибут не найден, это должно работать быстрее, чем бросать исключение.
Но в любом случае, наглядные результаты всегда надежней, чем сухая теория :)
getattr(obj, name, None) is not None я проверил:Групповой зачет:
getattr : 15.350072 [0 subtests failed]
Персональный зачет:
test_getattr_true_this_ca : 7.596199
test_getattr_true_parent_ca : 7.865653
test_getattr_true_this_ia : 8.003450
test_getattr_true_parent_ia : 8.811715
test_getattr_false : 22.630889getattr лучше прямого запроса свойства и отработку AttributeError, но хуже hasattr. Удивительно, но этот результат противоречит документации, потому что если hasattr реализован через getattr, то они должны были поменяться местами в общем рейтинге.getattr показывает себя с лучшей стороны, чем обработка исключения, и, думаю, его можно использовать там, где его можно использовать :) — в отличии от hasattr, он возвращает значение элемента.__dict__ — я не помню точно, где и как, но мне встречалась ситуация, где методу __getattribute__(self, name) передавался в качестве name '__dict__'.dir, но это отдельный разговор) возвращают булево значение — существует атрибут или нет. Даже при наличии __getattr__/__getattribute__ эти методы будут работать нормально, если «перехватчики» умеют сваливаться с AttributeError() при эмуляции отсутствии атрибута.
Ultimate benchmark пяти с половиной способов проверить наличие атрибута объекта в Python