2

外部クラス インスタンスで呼び出される外部クラス メソッドによってのみ異なる一連のクラス メソッドに、長い try/except1/except2/etc ブロックの繰り返しセットがあります。以下は簡略化されたバージョンです (実際には、私が処理している 4 つの例外と、呼び出されるインスタンス メソッドのみが異なる 8 つのメソッドがあります)。

class MyClass(object):
    def __init__(self):
        self.arg = 'foo'

    def method1(self, arg1):
        err = -1
        y = None
        try:
            x = AnOutsideClass(self.arg)     # Creates a class instance of an imported class
            y = x.outsideclassmethod1(arg1)  # Calls an instance method that returns another different class instance
        except MyException1:
            x.dosomething() # Needed to handle error
        except MyException2:
            err = 0
        finally:
            del x
        return y, err

    def method2(self, arg1, arg2, arg3):
        err = -1
        y = None
        try:
            x = AnOutsideClass(self.arg)
            y = x.outsideclassmethod2(arg1, arg2, arg3)  # This is the only thing changed
                                                         # A different method with different argument requirements
        except MyException1:
            x.dosomething()
        except MyException2:
            err = 0
        finally:
            del x
        return y, err

    def method3 ...

ネストされた関数、デコレータなどを使用してコードの try: 部分に 2 つのステートメントをラップすることで、このコードを凝縮するさまざまな方法を試してきましたが、他の例を翻訳するのに問題があるという事実のために失敗しているようですこれは、1) 後で except ブロックの 1 つで使用する必要があるクラス インスタンスを作成している、2) インスタンス メソッドを呼び出している、3) インスタンス メソッドの結果を返す必要がある、などの理由によるものです。

functoolsまたは記述子または他の手段から部分的にこれを達成する方法はありますか? 現在、ラッパー関数で使用する整数コードに基づいてインスタンス メソッドを選択する拡張 if/elif ブロックを使用した不格好な実装がありますが、もっと洗練された方法が必要だと考えています。私はPythonに比較的慣れておらず、途方に暮れています...

4

1 に答える 1

2

関数ファクトリ (つまり、関数を返す関数) を使用できます。

def make_method(methname):
    def method(self, *args):
        err = -1
        y = None
        try:
            x = AnOutsideClass(self.arg)     # Creates a class instance of an imported class
            y = getattr(x, methname)(*args)  # Calls an instance method that returns another different class instance
        except MyException1:
            x.dosomething() # Needed to handle error
        except MyException2:
            err = 0
        finally:
            del x
        return y, err
    return method

class MyClass(object):
    def __init__(self):
        self.arg = 'foo'
    method1 = make_method('outsideclassmethod1')
    method2 = make_method('outsideclassmethod2')

make_method外部メソッド名が文字列として渡されます 。指定された stringから実際のメソッドを取得するためにgetattr(内部で) 使用されます。 と同等です。methodxmethnamegetattr(x, 'foo')x.foo

*inは、任意の数の位置引数を受け入れることができることをPythondef method(self, *args)に伝えます。methodの中methodargsは、タプルがあります。*in は、要素 inを個々の引数として によって返されるメソッドに渡すy = getattr(x, methname)(*args)ように Python に指示します。解凍演算子については、こちらのドキュメントとこのブログで説明されますargsgetattr(x, methname)*

于 2014-11-04T21:37:41.540 に答える