以下を行うより良い方法はありますか?
try:
a.method1()
except AttributeError:
try:
a.method2()
except AttributeError:
try:
a.method3()
except AttributeError:
raise
それはかなり厄介に見え、私はむしろしたくない:
if hasattr(a, 'method1'):
a.method1()
else if hasattr(a, 'method2'):
a.method2()
else if hasattr(a, 'method3'):
a.method3()
else:
raise AttributeError
最大の効率を維持します。
おそらく、次のようなことを試すことができます。
def call_attrs(obj, attrs_list, *args):
for attr in attrs_list:
if hasattr(obj, attr):
bound_method = getattr(obj, attr)
return bound_method(*args)
raise AttributeError
次のように呼び出します。
call_attrs(a, ['method1', 'method2', 'method3'])
これは、リストにある順序でメソッドを呼び出そうとします。引数を渡したい場合は、リストの後に次のように渡すだけです。
call_attrs(a, ['method1', 'method2', 'method3'], arg1, arg2)
2番目の部分へのわずかな変更は、見栄えがよくシンプルです。 2つのパフォーマンスの違いに気付くとは思いませんが、これはネストされたtry/exceptsよりも少し優れています
def something(a):
for methodname in ['method1', 'method2', 'method3']:
try:
m = getattr(a, methodname)
except AttributeError:
pass
else:
return m()
raise AttributeError
他の非常に読みやすい方法は、実行することです。
def something(a):
try:
return a.method1()
except:
pass
try:
return a.method2()
except:
pass
try:
return a.method3()
except:
pass
raise AttributeError
長い間、関数が何をしているかは非常に明白です。パフォーマンスは実際には問題になりません(いくつかのtry/exceptステートメントがスクリプトの速度を著しく低下させる場合は、おそらくスクリプト構造に大きな問題があります)。
method = (
getattr(a, 'method1', None) or
getattr(a, 'method2', None) or
getattr(a, 'method3')
)
method()
これは最初にmethod1
、次にmethod2
、次にmethod3
を検索します。それらの1つが見つかるとすぐに検索が停止します。メソッドが見つからない場合、最後のgetattr
は例外を発生させます。
呼び出しを関数にカプセル化するのはどうですか?
def method_1_2_or_3():
try:
a.method1()
return
except AttributeError:
pass
try:
a.method2()
return
except AttributeError:
pass
try:
a.method3()
except AttributeError:
raise
コンパクトなソリューション:
getattr(a, 'method1',
getattr(a, 'method2',
getattr(a, 'method3')))()
新しいスタイルのオブジェクトを使用している場合:
methods = ('method1','method2','method3')
for method in methods:
try:
b = a.__getattribute__(method)
except AttributeError:
continue
else:
b()
break
else:
# re-raise the AttributeError if nothing has worked
raise AttributeError
もちろん、新しいスタイルのオブジェクトを使用していない場合は、__dict__
の代わりに __getattribute__
。
編集:このコードは悲鳴を上げる混乱であることが判明する可能性があります。 __getattribute__
または__dict__
が見つかりません。どのようなエラーが発生したかを大まかに推測してください。