2017-12-31 103 views
1

私は非常に簡単に書くことができますが、例外を処理する必要があるメソッドがたくさんあります。例外管理は常に同じなので、関数としてラッパーを記述し、特定の関数呼び出しインスタンスをパラメータとして呼び出すようにしたいと考えています。出来ますか?これらの線に沿って引数を引数として持つ関数を渡す方法

何か(これは非稼働イラストです):

def g(h): 
    while True: 
     try: 
      x = h() 
     except: 
      # got an error 
      print ("Unexpected error. Retry.") 
     else: 
      # everything is fine 
      return x 

def f1(x): 
    # do something that may fail (e.g. access a distant server) 
    y = (...whatever...) 
    return y 

def f2(x,y): 
    # do something else that may fail (e.g. access a distant server, but different request) 
    z = (...whatever...) 
    return z 

print (g(f1(3))) 
print (g(f1(6))) 
print (g(f2(5,'abc'))) 

注:私はクラス定義を必要としない答えを探しています。また、私はPythonのラムダ関数に精通していませんが、それはソリューションの一部である可能性がありますか?

+0

g成功するまで戻らない - あなたが望むものは? –

+0

はい、正確です。私はそれを言及すべきだった。実用的には、最大試行回数でタイムアウトを実装します。あなたのコードから – nekonaute

+0

- なぜそれは機能しませんか? haventはまだpyfiddleに投稿しましたが、合法的なようです... - '' args''と '** kwargs''(' https://stackoverflow.com/questions/36901/ 'g(f1,3)'のような種類の関数を必要とする追加のパラメータを 'g'が取ることを可能にするために、何もしないで二重星型のアスタリスクとスターのアスタリスクを使う'g'は与えられた関数に物を渡す必要があります.... –

答えて

1

最初の関数から関数を返す必要があります。私は、引数の数が可変可能にするために*演算子を使用しています

def g(h): 
    def f(*arguments): 
     try: 
      x = h(*arguments) 
     except: 
      # got an error 
      print ("Unexpected error. Retry.") 
     else: 
      # everything is fine 
      return x 
    return f 

https://docs.python.org/3/tutorial/controlflow.html#arbitrary-argument-lists

あなたは関数hとグラムを呼び出すたびに、それはいくつかの引数を指定して呼び出すことをするとき、意志あなたの関数を返します。それらを同じ引数で呼び出す(しかし、エラー処理の中で)。

あなたは今でそれを使用することができます。

g(f1)(3) 

また、あなたは新しい関数を作成しないように、グラム方式で直接*演算子を使用することができます。

def g(h, *arguments): 
    try: 
     x = h(*arguments) 
    except: 
     # got an error 
     print ("Unexpected error. Retry.") 
    else: 
     # everything is fine 
     return x 

あなたはそのようにそれを呼び出します。

g(f1, 3, 4) 

私はあなたが操作すること、安全機能を持つことができ、特にため、最初の代替クリーナーを見つける:

safe_f1 = g(f1) 
safe_f1(3) 
+2

ありがとう!それは機能します(私の評判は<15ですが、私は答えを押しました)。 – nekonaute

+1

私はあなたのためにそれを与える@nekonaute –

1

このかもしれませんヘルプ:

デコレータの使用

def exception_handler_wrapper(fn): 
    def new_fn(*args, **kwargs): 
     try: 
      result = fn(*args, **kwargs) 
     except Exception as e: 
      # return error string or print error string or log error string 
      # or do whatever suits you, with the exception 
      return "Error occured:" + str(e) 
     else: 
      return result 
    return new_fn 


@exception_handler_wrapper 
def f1(x): 
    # do something that may fail (e.g. access a distant server) 
    # emulating something that may fail: 
    if x % 2 == 0: 
     return "success" 
    else: 
     raise ValueError("x not even") 


@exception_handler_wrapper 
def f2(x, y): 
    # do something else that may fail (e.g. access a distant server, but 
    # different request) 
    # emulating something that may fail: 
    if x != 0 or y != 'abc': 
     return "success" 
    else: 
     raise Exception("Sum not 100") 

print("Expression f1(3):", f1(3)) 
print("Expression f1(6):", f1(6)) 
print("Expression f2(5, 'abc'):", f2(5, 'abc')) 

10と出力されました:例外あなたが処理したい任意の関数、それはdef initionだとあなただけのようなもの、それを呼び出すのでは通常、代わりにその関数を呼び出すことができます前に、ちょうど@exception_handler_wrapperを置くと今

Expression f1(3): Error happend:x not even 
Expression f1(6): success 
Expression f2(5, 'abc'): success 

g(f1(6))

関連する問題