2016-05-29 12 views
0

私は2つのクラスを用意していますが、そのうちの1つは設定コストが高く再利用可能ですが、もう1つはアプリケーションに多くのインスタンスを持ちますが、高価なクラスのインスタンスを再利用できます。これは、例えばによって説明することが容易である:あなたが、私は基本的に財産の最初の使用上の特性をmemoizeする@staticmethod@propertyを使用することを望ん、ないサイコロた見ることができるようにPythonの静的プロパティのメモ帳

class SomeExpensiveToSetUpClass(object): 
    def __init__(self): 
     print("Expensive to set up class initialized") 
     self.whatever = "Hello" 

    def do_the_thing(self): 
     print(self.whatever) 

class OftenUsedClass(object): 

    @staticmethod 
    @property 
    def expensive_property(): 
     try: 
      return OftenUsedClass._expensive_property 
     except AttributeError: 
      OftenUsedClass._expensive_property = SomeExpensiveToSetUpClass() 
      return OftenUsedClass._expensive_property 

    # I know I could hide the static property in an instance property: 
    @property 
    def expensive_property2(self): 
     try: 
      return OftenUsedClass._expensive_property 
     except AttributeError: 
      OftenUsedClass._expensive_property = SomeExpensiveToSetUpClass() 
      return OftenUsedClass._expensive_property 
    # 
    # And then: 
    # 
    # ouc = OftenUsedClass() 
    # ouc.expensive_property2.do_the_thing() 
    # ouc.expensive_property2.do_the_thing() 
    # ouc.expensive_property2.do_the_thing() 
    # 
    # but that feels misleading 

if __name__ == '__main__': 
    OftenUsedClass.expensive_property.do_the_thing() 
    OftenUsedClass.expensive_property.do_the_thing() 
    OftenUsedClass.expensive_property.do_the_thing() 

- 私は」 mは代わりにバックpropertyのインスタンスを取得:

Traceback (most recent call last): 
    File "memo.py", line 39, in <module> 
    OftenUsedClass.expensive_property.do_the_thing() 
AttributeError: 'property' object has no attribute 'do_the_thing' 

私がメモ化デコレータのためのいくつかのパターンを見つけたが、いずれも静的プロパティに。何か不足していますか?または、私は使用すべき別のパターンがありますか?

編集:

私は私の質問を単純化:私はSomeExpensiveToSetUpClassクラス実装の名前は設定ファイルで供給され、私は最初の時までにその名前を知らないということが含まれている必要がありますOftenUsedClassがインスタンス化されます。

+1

あなたのサンプルがむしろ複雑なので、私はあなたに従うかどうか分かりませんが、 'SomeExpensiveToSetUpClass()'をシングルトンに変換することはできません(そのクラスのインスタンスは1つだけです)。 "OftenUsedClass"をそのシングルトンに? –

+0

@Rogalski - ありがとう!なぜシングルトンが不可能なのかを明確にしました。申し訳ありませんが、最初は十分にはっきりしていませんでした。 – JStroop

+0

おそらく、これは[遅れて計算されたクラス属性を記述する](http://stackoverflow.com/questions/18289871/lazy-class-property-decorator)でしょう。 '@class_reify def expensive_property():return SomeExpensiveToSetUpClass()' –

答えて

0

提案されたpossible duplicateは近いです。

class classproperty(object): 
    def __init__(self, getter): 
     self.getter = getter 
    def __get__(self, instance, owner): 
     return self.getter(owner) 

が、そう、クラスの外で何かを定義する必要はありません:その答えに記載されclassmethodデコレータは作品

class OftenUsedClass(object): 

    @classproperty 
    def expensive_property3(cls): 
     try: 
      return cls._expensive_property 
     except AttributeError: 
      cls._expensive_property = SomeExpensiveToSetUpClass() 
      return cls._expensive_property 
正常に動作します

+0

あなたはそれが近いということを意味しますか?これはちょうど[その答え](http://stackoverflow.com/a/3203659/5827215)の詳細です、 'x = 4'はそのユーザー固有のケースです。 –

+0

私は謝罪する:その答えで私はなぜ 'Foo.x'が十分でないのか分からない。多分私は何かを欠いているでしょうか? – JStroop

+0

私はその例を 'expensive_property'メソッドの外に' _expensive_property'を定義しなければならないことを示唆しています。 – JStroop