例外がスローされると考える頻度に大きく依存します。
私の意見では、両方のアプローチは、少なくとも読みやすさとpythonic-nessの点では等しく有効です。ただし、オブジェクトの90%に属性がないbar
場合は、2つのアプローチのパフォーマンスに明確な違いがあります。
>>> import timeit
>>> def askforgiveness(foo=object()):
... try:
... x = foo.bar
... except AttributeError:
... pass
...
>>> def askpermission(foo=object()):
... if hasattr(foo, 'bar'):
... x = foo.bar
...
>>> timeit.timeit('testfunc()', 'from __main__ import askforgiveness as testfunc')
2.9459929466247559
>>> timeit.timeit('testfunc()', 'from __main__ import askpermission as testfunc')
1.0396890640258789
あなたのオブジェクトの90%はならない属性を持って、テーブルを回転されています:
>>> class Foo(object):
... bar = None
...
>>> foo = Foo()
>>> timeit.timeit('testfunc(foo)', 'from __main__ import askforgiveness as testfunc, foo')
0.31336188316345215
>>> timeit.timeit('testfunc(foo)', 'from __main__ import askpermission as testfunc, foo')
0.4864199161529541
そのため、パフォーマンスの観点から、環境に最適なアプローチを選択する必要があります。
最終的に、timeit
モジュールの戦略的な使用は、あなたができる最もPython的なものかもしれません。