私はPythonクラスFooを持っているシナリオを扱っています。Fooは、とりわけ、多くの大きな計算を行いますが、必要な場合を除いて、私はそれを行いません。したがって、これらの大きな計算の1つに対してgetterメソッドを定義する場合、計算に対応するメソッド(ここではbigcalculation())がすでに実行されていることを確認するにはどうすればよいですか?
class Foo:
def __init__(self):
#initialize some stuff
def bigcalculation(self):
#perform calculation
self.big_calc_result=[big list of numbers];
def get_big_calc_result(self):
if hasattr(self,'big_calc_result')==False:
self.bigcalculations();
return sef.big_calc_result;
一度実行した場合、再度実行したくありません。発信者が一度実行したかどうかを追跡する必要はありません。
今、私は上記のようにhasattr()関数を使用してそれを行いますが、これは本当に醜い方法だと思います。それを行うためのよりエレガントなpythonicの方法はありますか?
私が考えることができる別の方法は、init()関数で、クラスで使用するすべての変数を空のリストとして定義することです。次に、big_calc_resultが空のリストであるかどうかを確認して、self.bigcalculation()がすでに実行されているかどうかを判別します。これはより良いアプローチですか?
関連する質問:Pythonを使用すると、クラス内でその場で変数を定義できます。しかし、それは悪いプログラミング慣行ですか?
編集:振り返ってみると、例外を使用することもこの状況を処理する別の方法である可能性があることもわかりました。それは物事を行うためのよりパイソン的な方法かもしれません。
def get_big_calc_result(self):
try:
return self.big_calc_result;
except AttributeError:
self.bigcalculations();
return self.big_calc_result;
この質問への回答は役に立ちます:Pythonでのメンバーの存在の確認
結果をメモして、プロパティとして保存できます。
class Foo(object):
def __init__(self):
self._big_calc_result = None
@property
def big_calc_result(self):
if self._big_calc_result is not None:
return self._big_calc_result
else:
self._big_calc_result = self.big_calc_run()
return self._big_calc_result
def big_calc_run(self):
time.sleep(10) # Takes a long time ...
これで、クラスを初期化して結果を取得するだけです。
f = Foo()
x = f.big_calc_result
y = f.bic_calc_result # Look mom, this happened really quick
もちろん、直感的でない場合はプロパティを使用する必要はありません。提供しようとしているAPIに合わせて、このあたりで変更を加えることができます。本当の意味は、アンダースコアが前に付いた変数に結果をキャッシュすることです。つまり、「これは実装の詳細です。これを台無しにした場合、将来のある時点でコードを中断する価値があります」。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加