2017-09-12 4 views
0

キャッシュが関数オブジェクトとその引数に基づいているキャッシングツールのテストを設定しようとしています。このテストを行うには、自分のプロパティで呼び出されている関数にアクセスする必要があります。これを行う方法を理解できません。子クラスから親クラスのプロパティゲッターにアクセスする

キャッシュコードは次のようになります。

def cached(func): 
    """ 
    Decorator to cache function calls 
    """ 

    @wraps(func) 
    def wrapper(self, *args): 
     # The cache lives in the instance so that it gets garbage collected 
     if (func, args) not in self._cache: 
      self._cache[(func, args)] = func(self, *args) 
     return self._cache[(func, args)] 

    return wrapper 

と私はキャッシュされたプロパティを持っている:

class SpatialMixin(object): 
    @property 
    @cached 
    def longitude_extrema(self): 
     return 25 

クラスは、このようなものになります。私がアクセスできる

class MainClass(SomeOtherBaseClass,SpatialMixin): 
    pass 

MyObject = MainClass() 

base_class.SpatialMixin.longitude_extrema.fget直接、これは別のオブジェクトですMyObject.longitude_extrema.fget(これは私ですそのプロパティのゲッタを示すために使用します。 MyObject.longitude_extremaは25番なので、この方法でアクセスすることはできません)。

したがって、MyObject.longitude_extremaプロパティの基礎となる関数にはどのようにアクセスできますか?

+0

「SpatialMixin.longitude_extrema.fget」は間違ったゲッターであると思いますか? – user2357112

+1

キャッシュラッパーがラッピングしている関数にアクセスしようとしている場合、それはゲッターではありません。キャッシュラッパーはゲッターです。ラップされた関数をラッパーなどの属性として使用できるようにすることができます。 – user2357112

+0

私はコマンドラインからチェックし、キャッシュキーの関数の 'id'は' SpatialMixin.longitude_extrema.fget'とは異なります。しかし、getter(つまり、関数 'longitude_extrema')がラップされた関数ではない場合は...何ですか? – keflavich

答えて

1

元のlongitude_extrema機能にアクセスしようとしている場合は、元のlongitude_extrema機能がゲッターではないため、fgetで見つからないことがあります。 cachedデコレータで作成されたwrapper関数がゲッタです。

Python 3.4以降では、functools.wrapsで修飾されたラッパーには、ラップする関数を指す__wrapped__属性があります。これを使用して元のlongitude_extremaにアクセスできます。 (この属性は3.2と3.3にも存在しますが、少しばらつきがあります)

Python 2では、functools.wraps__wrapped__に設定されていません。とにかくラップされた関数を直接クロージャー操作で得ることは技術的には可能ですが、それは扱いにくく、変数名に依存していて、特にデコレータを制御しているため、良い選択肢ではありません。 cachedデコレータで__wrapped__を自分で設定することもできます。

関連する問題