2017-07-06 8 views
1

私がやろうとしているのは、ほかのモジュールのメソッドに渡されているパラメータを変換できるように、別のモジュールの周りにラッパーを書き込むことです。Python:関数のパラメータを変更するメソッド呼び出しをインターセプトする方法はありますか?

import somemodule 

class Wrapper: 
    def __init__(self): 
     self.transforms = {} 
     self.transforms["t"] = "test" 

    # This next function is the one I want to exist 
    # Please understand the lines below will not compile and are not real code 
    def __intercept__(self, item, *args, **kwargs): 
     if "t" in args: 
      args[args.index("t")] = self.transforms["t"] 
     return somemodule.item(*args, **kwargs) 

目標は、ラッパークラスのユーザーは、モジュール内のすべての機能を書き換えることなく、基礎となるモジュールに単純化された呼び出しを行うことができるようにすることです:それはので、ここでの例で、かなり混乱しました。 somemoduleprint_uppercaseと呼ばれる機能を持っていたのであれば、この場合には、ユーザが

w = Wrapper() 
w.print_uppercase("t") 

を行うと、私は答えは__getattr__であると考えているが、私はどのように完全にはよく分からない出力

TEST 

を得ることができますこのアプリケーションに使用してください。

+0

@ D.Peterは、これがどのように適用されるかの例をまとめることができますか?私はあなたを信じています、私はちょうど嘲笑の文書とちょっと混乱しています。 –

答えて

1

__getattr__は動作するはずです:

# somemodule 

def print_uppercase(x): 
    print(x.upper()) 

今:

from functools import wraps 

import somemodule 

class Wrapper: 
    def __init__(self): 
     self.transforms = {} 
     self.transforms["t"] = "test" 

    def __getattr__(self, attr): 
     func = getattr(somemodule, attr) 
     @wraps(func) 
     def _wrapped(*args, **kwargs): 
      if "t" in args: 
       args = list(args) 
       args[args.index("t")] = self.transforms["t"] 
      return func(*args, **kwargs) 
     return _wrapped 


w = Wrapper() 
w.print_uppercase('Hello') 
w.print_uppercase('t') 

出力:

HELLO 
TEST 
+0

'* args'は' args'がどのようなシーケンスであるか気にしないので、最初にタプルを作成する必要はありません。 – chepner

+0

@chepnerありがとうございます。一定。 –

+0

@MikeMüllerこれは私がちょうど一緒にハックしようとしていたものです。ありがとう。 –

0

私は、インターセプトメソッドを呼び出し、インターセプトのパラメータとして実行する目的のメソッドを入力することでこれにアプローチします。次に、interceptメソッドで、その名前のメソッドを検索して実行することができます。

+0

これは実行可能ですが、かなり醜いです。また、人々が基盤となるモジュールの使用に慣れていく方法を打破します。 –

0

Wrapperオブジェクトには可変状態がないため、クラスなしで実装する方が簡単です。例wrapper.py:次に

def func1(*args, **kwargs): 
    # do your transformations 
    return somemodule.func1(*args, **kwargs) 

好きそれを呼び出す:

場で関数を定義すると組み合わせる
import wrapper as w 
print w.func1('somearg') 
関連する問題