Forum Programmation.python Accès à la liste des méthodes de l'intérieur d'une classe

Posté par  (site web personnel) .
Étiquettes : aucune
1
27
août
2010
Bonjour,

je voudrais accéder à la liste des méthodes à l'intérieur d'une classe.

Ce que je voudrais faire, c'est appeler une autre méthode de la classe avec une chaîne de caractère plutôt que self.methode, histoire de pouvoir faire des fonctions génériques du style de meth1 dans l'exemple suivant :

class = ThisClass(object):
....def meth1(self, var):
........for i in range(3)
........self.__dict__['othermeth' + str(i)](var)
....def othermeth0(self, var):
........#do smth
........pass
....def othermeth1(self, var):
........#do smth
........pass
....def othermeth2(self, var):
........#do smth
........pass

Bien sûr, self.__dict__ ne marche pas car il ne contient que les instances de la classe et non les méthodes...

Merci pour votre aide !
  • # arf

    Posté par  (site web personnel) . Évalué à 1.

    désolé pour l'erreur de la définition de la classe...

    class ThisClass(object):
    • [^] # Re: arf

      Posté par  (site web personnel) . Évalué à 1.

      avec la primitive getattr():

      ....def meth1(self, var):
      ........for i in range(3):
      ........ getattr(self, 'othermeth' + str(i))(var)

      Et voilà :D
      • [^] # Re: arf

        Posté par  (site web personnel) . Évalué à 1.

        C'est si simple !!!??

        Mais pourquoi getattr pour attraper une méthode ????

        ou alors j'ai rien compris à la programmation objet...

        En tout cas merci, tu vas me permettre de simplifier mon code.
        • [^] # Re: arf

          Posté par  . Évalué à 2.

          Y’a aussi une méthode générique : mon_objet.__getattr__(mon_attribut) (c’est sûrement cette méthode que getattr appelle en fait.
        • [^] # Re: arf

          Posté par  (site web personnel) . Évalué à 1.

          En Python, les méthodes sont des attributs comme les autres SAUF qu'ils sont des attributs de la classe et non de l'instance:

          >>> class toto:
          ............def meth(self):
          ...............pass
          ...
          >>> t=toto()
          >>> t.__dict__
          {}
          >>> toto.__dict__
          {'__module__': '__main__', 'meth': <function meth at 0xb77cdb8c>, '__doc__': None}

          Il est de toutes façons déconseillé d'accéder directement au dictionnaire d'instances (__dict__). getattr() te permet d'accéder à tous les attributs de tes objets.
          • [^] # Re: arf

            Posté par  (site web personnel) . Évalué à 3.

            Pas tout à fait, selon que l'on parle de la méthode de classe ou de la méthode d'instance de classe, Python ne nous crée pas les méthode de la même manière : les méthodes d'instances sont des méthodes liées ( bound method ), alors que celles de classes ne le sont pas. ( C'est ce qui correspond au self passé en premier argument de chacune des méthodes ).

            >>> class A(object):
            .........def func(self):
            ...............pass
            ...

            >>> A.func
            <unbound method A.func>
            >>> a = A()
            >>> a.func
            <bound method A.func of <__main__.A object at 0xb775da6c>>
            >>>

            Cela signifie que la méthode est liée à une instance et qu'il n'est pas possible de l'utiliser de manière séparée de l'instance ( c'est le but de la propriété im_self ) :

            >>> my_func= a.func
            >>> my_func.im_self
            <__main__.A object at 0xb775da6c>

            >>> my_func.im_self == a
            True

            C'est pas explicite dans Python, et cela peut poser des problèmes difficile à comprendre au moment où l'on s'y retrouve confronté.
            • [^] # Re: arf

              Posté par  (site web personnel) . Évalué à 2.

              Un autre exemple un peu plus parlant :

              >>> class A(object):
              ........def __init__(self, name):
              .............self.name = name
              ........def func(self):
              .............print self.name
              ...

              On crée deux instances :

              >>> a1 = A(1)
              >>> a2 = A(2)

              Les trois appels renvoient la même valeur :

              >>> a1.func()
              1
              >>> A.func(a1)
              1
              >>> a2.func.im_func(a1)
              1

              Pourtant, la méthode (unbound) de classe n'est pas le même objet que la fonction associée à la méthode d'instance :

              >>> a2.func.im_func == A.func
              False
              • [^] # Re: arf

                Posté par  . Évalué à 2.

                duh, le dernier exemple est l'exemple de trop !

                Si j'ai lu correctement, la méthode func est "bound" / liée mais cela ne signifie pas que self soit figé. On peut visiblement faire appel à a2.func.im_func avec self == a1.

                Je n'ose même pas imaginer comment un tel découplage pourrait-être exploité...
                • [^] # Re: arf

                  Posté par  (site web personnel) . Évalué à 3.

                  Si j'ai lu correctement, la méthode func est "bound"
                  mu !

                  En fait a1.func est liée, mais A.func ne l'est pas. On ne peut pas évoquer la méthode func sans évoquer la manière dont celle-ci a été invoquée.

                  Quand on utilise im_func sur une méthode liée, python nous renvoie la fonction ( non plus la méthode ).

                  >>> a1.func.im_func
                  <function func at 0x7f9543c1b5f0>

                  >>> A.func.im_func
                  <function func at 0x7f9543c1b5f0>

                  Aucune des deux n'est liée à la classe en question, c'est pourquoi on peut passer une autre instance d'un autre objet, voire même d'une autre classe :


                  >>> class A(object):
                  ........def __init__(self, name):
                  .............self.name = name
                  ........def func(self):
                  .............print self.name
                  ...
                  >>> class B(object):
                  ........def __init__(self, name):
                  .............self.name = name
                  ...
                  >>> b1 = B(1)
                  >>> A.func.im_func(b1)
                  1


                  C'est vraiment dommage que la doc python n'aborde pas ce point, car c'est vraiment important dès qu'on va un peu en profondeur dans le langage.

                  Je n'ose même pas imaginer comment un tel découplage pourrait-être exploité...

                  Pour ma part j'en avais eu besoin pour mettre en place un système d'évènement dans une appli. La difficultée étant de sauvegarder la méthode pour l'appeller lors du déclenchement de l'évenement, tout en gardant une référence faible sur l'objet auquel la méthode est liée…
                  • [^] # Re: arf

                    Posté par  . Évalué à 2.

                    Hum, il me semble avoir confondu A.func et A.func.im_func, ainsi que méthode et fonction, dans mon commentaire précédent. En tout cas, merci pour les explications supplémentaires.

                    Je suis bien content de (ré-)apprendre ce genre de choses intéressantes ;-)

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.