143 votes

Python: Lier un Indépendant Méthode?

En Python, il est un moyen de lier un indépendant méthode sans appel?

Je suis en train d'écrire un wxPython programme, et, pour une certaine classe j'ai décidé qu'il serait bien de regrouper les données de tous mes boutons de l'ensemble des élèves de niveau liste de tuples, comme suit:

class MyWidget(wx.Window):
    buttons = [("OK", OnOK),
               ("Cancel", OnCancel)]

    # ...

    def Setup(self):
        for text, handler in MyWidget.buttons:

            # This following line is the problem line.
            b = wx.Button(parent, label=text).Bind(wx.EVT_BUTTON, handler)

Le problème est, depuis toutes les valeurs de handler sont indépendant de méthodes, de mon programme explose dans un spectaculaire incendie et je pleure.

Je regardais autour de moi en ligne pour une solution à ce qui semble être devrait être relativement simple, nous pouvons résoudre problème. Malheureusement, je ne pouvais pas trouver quoi que ce soit. Maintenant, je suis à l'aide d' functools.partial pour contourner ce problème, mais personne ne sait si il y a un nettoyage sentiment, en bonne santé, Pythonic moyen de lier un indépendant méthode d'une instance et de continuer à transmettre autour sans appel?

212voto

Alex Martelli Points 330805

Toutes les fonctions sont également des descripteurs, de sorte que vous pouvez lier à eux en les appelant par leurs __get__ méthode:

bound_handler = handler.__get__(self, MyWidget)

Voici R. Hettinger excellent guide pour les descripteurs.

96voto

Kiv Points 9116

Cela peut être fait proprement avec les types.MethodType. Exemple:

import types

def f(self): print self

class C(object): pass

meth = types.MethodType(f, C(), C) # Bind f to an instance of C
print meth # prints <bound method C.f of <__main__.C object at 0x01255E90>>

12voto

Kazark Points 2453

La création d'une fermeture avec soi dans l', il ne sera pas techniquement lier la fonction, mais c'est une autre façon de résoudre le même (ou très similaire) problème sous-jacent. Voici un exemple trivial:

self.method = (lambda self: lambda args: self.do(args))(self)

10voto

user83591 Points 3857

Cela permettra de lier self de handler:

bound_handler = lambda *args, **kwargs: handler(self, *args, **kwargs)

Cela fonctionne en passant self comme premier argument de la fonction. object.function() est juste sucre syntaxique pour function(object).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X