0

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 では、クラス内でオンザフライで変数を定義できます。しかし、それは悪いプログラミング習慣ですか?

編集:振り返ってみると、例外を使用することも、この状況を処理する別の方法になる可能性があることがわかりました。それは物事を行うためのよりpythonicな方法かもしれません。

def get_big_calc_result(self):
    try:
        return self.big_calc_result;
    except AttributeError:
        self.bigcalculations();
        return self.big_calc_result;

この質問に対する答えは役に立ちます: Python でのメンバーの存在の確認

4

1 に答える 1

2

結果をメモして、プロパティとして保存できます。

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 に合わせて、このあたりを変更できます。本当の意味は、アンダースコアが前に付いた変数に結果をキャッシュすることです。これは、「これは実装の詳細です。これをいじると、将来のある時点でコードが壊れるに値します」ということです。

于 2014-06-25T03:41:24.640 に答える