Question

Est-il possible d'adopter une méthode en tant que paramètre à une méthode?

self.method2(self.method1)

def method1(self):
    return 'hello world'

def method2(self, methodToRun):
    result = methodToRun.call()
    return result
Était-ce utile?

La solution

Oui il est, il suffit d'utiliser le nom de la méthode, comme vous l'avez écrit. Méthodes / fonctions sont des objets en Python, comme tout le reste, et vous pouvez les passer autour de la façon dont vous faites des variables. En fait, vous pouvez penser à une méthode (ou la fonction) comme une variable dont la valeur est l'objet de code appelable réel.

Pour votre information, il n'y a pas de méthode de call - Je pense qu'il est appelé __call__, mais vous ne devez pas l'invoquer explicitement:

def method1():
    return 'hello world'

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

method2(method1)

Si vous voulez method1 être appelé avec des arguments, alors les choses deviennent un peu plus compliqué. method2 doit être écrit avec un peu d'informations sur la façon de passer des arguments à method1, et il a besoin pour obtenir des valeurs pour les arguments de quelque part. Par exemple, si method1 est censé prendre un argument:

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

vous pouvez écrire method2 appeler avec un argument qui est passé dans:

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

ou avec un argument selon lequel il se calcule:

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

Vous pouvez étendre cela à d'autres combinaisons de valeurs passées et les valeurs calculées, comme

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)

ou même avec des arguments de mots clés

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

Si vous ne savez pas, lors de l'écriture method2, quels arguments methodToRun va prendre, vous pouvez également utiliser l'argument de déballer l'appeler d'une manière générique:

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'})

Dans ce cas positional_arguments doit être une liste ou tuple ou similaire, et keyword_arguments est un dict ou similaire. En method2 vous pouvez modifier positional_arguments et keyword_arguments (par exemple pour ajouter ou supprimer certains arguments ou modifier les valeurs) avant d'appeler method1.

Autres conseils

Oui, il est possible. Il suffit de l'appeler:

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

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

Voici votre exemple re-écrit pour montrer un exemple de travail autonome:

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()

Oui; (fonctions et méthodes) sont les premiers objets de classe en python. Les travaux suivants:

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

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

foo(bar)

Sorties:

Running parameter f().
In bar().

Ces sortes de questions sont très simples à répondre en utilisant l'interpréteur Python ou, pour plus de fonctionnalités, IPython .

Si vous voulez passer une méthode d'une classe comme un argument, mais n'ont pas encore l'objet sur lequel vous allez l'appeler, vous pouvez tout simplement passer l'objet une fois que vous l'avez comme premier argument (la argument "auto").

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)

imprimera "Bonjour tout le monde"

Les méthodes sont des objets comme les autres. Ainsi, vous pouvez les faire passer, de les stocker dans des listes et dicts, faites tout ce que vous aimez avec eux. La chose particularité est qu'ils sont des objets appelables de sorte que vous pouvez invoquer __call__ sur eux. __call__ est appelée automatiquement lorsque vous invoquez la méthode avec ou sans arguments que vous avez juste besoin d'écrire methodToRun().

Beaucoup de bonnes réponses, mais étrange que personne ne l'a mentionné en utilisant une fonction de lambda.
Donc, si vous avez pas d'arguments, les choses deviennent assez trivial:

def method1():
    return 'hello world'

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

method2(method1)

Mais que vous avez un des arguments en method1 (ou plus):

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

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

Ensuite, vous pouvez simplement invoquer method2 comme method2(lambda: method1('world')).

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

Je trouve cela beaucoup plus propre que les autres réponses mentionnées ici.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top