web-dev-qa-db-ja.com

メソッドをPythonのパラメーターとして渡す方法

メソッドにパラメーターとしてメソッドを渡すことは可能ですか?

self.method2(self.method1)

def method1(self):
    return 'hello world'

def method2(self, methodToRun):
    result = methodToRun.call()
    return result
152
Dan

はい、そうです、あなたが書いたように、単にメソッドの名前を使用してください。メソッド/関数は、他のPythonと同様にPythonのオブジェクトであり、変数を実行する方法で渡すことができます。実際、メソッド(または関数)は、その値が実際の呼び出し可能なコードオブジェクトである変数として考えることができます。

参考までに、callメソッドはありません-__call__と呼ばれていますが、明示的に呼び出す必要はありません。

def method1():
    return 'hello world'

def method2(methodToRun):
    result = methodToRun()
    return result

method2(method1)

method1を引数付きで呼び出す場合は、少し複雑になります。 method2は、method1に引数を渡す方法についての少しの情報を記述する必要があり、それらの引数の値をどこかから取得する必要があります。たとえば、method1が1つの引数を取る場合:

def method1(spam):
    return 'hello ' + str(spam)

method2を記述して、渡される1つの引数で呼び出すことができます。

def method2(methodToRun, spam_value):
    return methodToRun(spam_value)

または、それ自体を計算する引数を使用します。

def method2(methodToRun):
    spam_value = compute_some_value()
    return methodToRun(spam_value)

これを、次のように、渡された値と計算された値の他の組み合わせに拡張できます。

def method1(spam, ham):
    return 'hello ' + str(spam) + ' and ' + str(ham)

def method2(methodToRun, ham_value):
    spam_value = compute_some_value()
    return methodToRun(spam_value, ham_value)

またはキーワード引数でも

def method2(methodToRun, ham_value):
    spam_value = compute_some_value()
    return methodToRun(spam_value, ham=ham_value)

method2を記述するときにmethodToRunがどの引数を取るかわからない場合は、引数のアンパックを使用して一般的な方法で呼び出すこともできます。

def method1(spam, ham):
    return 'hello ' + str(spam) + ' and ' + str(ham)

def method2(methodToRun, positional_arguments, keyword_arguments):
    return methodToRun(*positional_arguments, **keyword_arguments)

method2(method1, ['spam'], {'ham': 'ham'})

この場合、positional_argumentsはリストまたはTupleまたは類似のものである必要があり、keyword_argumentsはdictまたは類似のものである必要があります。 method2では、positional_argumentsを呼び出す前に、keyword_argumentsおよびmethod1を変更できます(たとえば、特定の引数を追加または削除したり、値を変更したりできます)。

217
David Z

はい、可能です。それを呼ぶだけです:

class Foo(object):
    def method1(self):
        pass
    def method2(self, method):
        return method()

foo = Foo()
foo.method2(foo.method1)
33
unbeknown

スタンドアロンの動作例を示すために書き直された例を次に示します。

class Test:
    def method1(self):
        return 'hello world'

    def method2(self, methodToRun):
        result = methodToRun()
        return result

    def method3(self):
        return self.method2(self.method1)

test = Test()

print test.method3()
12
Trent

はい;関数(およびメソッド)はPythonのファーストクラスオブジェクトです。次の作品:

def foo(f):
    print "Running parameter f()."
    f()

def bar():
    print "In bar()."

foo(bar)

出力:

Running parameter f().
In bar().

これらの種類の質問は、Pythonインタープリターを使用するか、より多くの機能については IPython Shellを使用して答えるのは簡単です。

5
lt_kije

クラスのメソッドを引数として渡したいが、それを呼び出すオブジェクトがまだない場合は、最初の引数としてオブジェクトを渡せばよいだけです(つまり、「self」引数)。

class FooBar:

    def __init__(self, prefix):
        self.prefix = prefix

    def foo(self, name):
        print "%s %s" % (self.prefix, name)


def bar(some_method):
    foobar = FooBar("Hello")
    some_method(foobar, "World")

bar(FooBar.foo)

これにより、「Hello World」が印刷されます。

3
FrontSide

良い答えはたくさんありますが、lambda関数の使用について誰も言及していないのは奇妙です。
したがって、引数がない場合は、非常に簡単になります。

def method1():
    return 'hello world'

def method2(methodToRun):
    result = methodToRun()
    return result

method2(method1)

ただし、method1に1つ(または複数)の引数があるとしましょう。

def method1(spam):
    return 'hello ' + str(spam)

def method2(methodToRun):
    result = methodToRun()
    return result

その後、method2method2(lambda: method1('world'))として単純に呼び出すことができます。

method2(lambda: method1('world'))
>>> hello world
method2(lambda: method1('reader'))
>>> hello reader

ここで述べた他の答えよりもずっときれいだと思います。

2
Scrotch

メソッドは、他のオブジェクトと同様のオブジェクトです。そのため、それらを渡したり、リストや辞書に保存したり、好きなことをしたりできます。それらの特別な点は、呼び出し可能なオブジェクトであるため、__call__を呼び出すことができます。 __call__は、引数付きまたは引数なしでメソッドを呼び出すと自動的に呼び出されるため、必要なのはmethodToRun()と記述するだけです。

2
Vasil