IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Ajout dynamique de méthode et functools.partial


Sujet :

Python

  1. #1
    Membre éclairé
    Homme Profil pro
    Ingénieur R&D en apprentissage statistique
    Inscrit en
    Juin 2009
    Messages
    447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur R&D en apprentissage statistique

    Informations forums :
    Inscription : Juin 2009
    Messages : 447
    Points : 752
    Points
    752
    Par défaut Ajout dynamique de méthode et functools.partial
    Bonjour,

    Je suis récemment tombé sur ce que je pense être une bizarrerie en essayant d'ajouter des méthodes à la volée à une classe. Voici un bout de code qui reproduit mon problème en Python 2.7:

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    from functools import partial
     
    def print_var(obj, var):
        print obj.__class__.__name__ + ": " + var
     
    class VarPrint(object):
        pass
     
    VarPrint.print_something = lambda obj: print_var(obj, "something")
    VarPrint.print_something_else = partial(print_var, var="something else")
     
    a = VarPrint()
    a.print_something()
    partial(print_var, var="another one")(a)
    a.print_something_else()
    avec pour résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    VarPrint: something
    VarPrint: another one
    Traceback (most recent call last):
      ...
        a.print_something_else()
    TypeError: print_var() takes exactly 2 arguments (1 given)
    Pourquoi l'utilisation de partial ne fonctionne pas comme attendu ?

  2. #2
    Membre éclairé
    Homme Profil pro
    Ingénieur R&D en apprentissage statistique
    Inscrit en
    Juin 2009
    Messages
    447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur R&D en apprentissage statistique

    Informations forums :
    Inscription : Juin 2009
    Messages : 447
    Points : 752
    Points
    752
    Par défaut
    J'ai je pense trouvé moi-même la réponse.

    La séquence d'appel doit être quelque chose comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    a = MaClass()
    a.use_something_else()
    qui se traduit par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaClass.something_else.__call__(a)
    Or `something_else` ici est un objet `Partial` donc ici avec la signature `something_else.__call__(self, *args, **kwargs)`.
    c'est donc `a` qui est passé à `something_else.__call__` au lieu de l'objet `Partial` lui même.

    Edit: la solution que j'avais cru trouver ne marche pas.

  3. #3
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> class A(object):
    ...     pass
    ... 
    >>> def func(self):
    ...     print "hello world!"
    ... 
    >>> A.func_class = func
    >>> a = A()
    >>> a.func_class()
    hello world!
    Non?
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Quand on essaie une construction qui ne fonctionne pas, commencer par relire la documentation s'impose:
    partial objects are like function objects in that they are callable, weak referencable, and can have attributes. There are some important differences. For instance, the __name__ and __doc__ attributes are not created automatically. Also, partial objects defined in classes behave like static methods and do not transform into bound methods during instance attribute look-up.
    Dans la pratique, çà veut dire qu'il faudra faire comme dans le cas du "lambda":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    from functools import partial
     
    def print_var(obj, var):
        print type(obj).__name__ + ": " + var
     
    class VarPrint(object):
        pass
     
    VarPrint.print_something = lambda obj: print_var(obj, "something")
    VarPrint.print_something_else = lambda obj: partial(print_var, var="something else")(obj)
     
    a = VarPrint()
    a.print_something()
     
    partial(print_var, var="another one")(a)
    a.print_something_else()
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. [VBA] Ajouter dynamiquement une référence
    Par jpharand dans le forum VBA Access
    Réponses: 23
    Dernier message: 16/04/2010, 23h28
  2. [C#] Ajout d'une méthode à la classe DropDownList
    Par Scorff dans le forum ASP.NET
    Réponses: 2
    Dernier message: 30/08/2005, 14h23
  3. ajouter dynamiquement des items dans un popup menu
    Par Malone dans le forum Composants VCL
    Réponses: 7
    Dernier message: 23/08/2005, 16h08
  4. Réponses: 2
    Dernier message: 10/05/2005, 15h54
  5. Ajout dynamique d'un contrôle à une fenêtre
    Par Yacine95000 dans le forum MFC
    Réponses: 6
    Dernier message: 08/06/2004, 16h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo