Vous êtes ici : Accueil / Forums & ML / Forums Python / Forum général Python / Comment faire des fonctions virtuelles et des classes abstraites proprement en python

Comment faire des fonctions virtuelles et des classes abstraites proprement en python

Remonter à Forum général Python
  • Comment faire des fonctions virtuelles et des classes abstraites proprement en python

    Envoyé par figo le 8 Novembre 2005 à 19:13
    Bonjour,
    je viens de débuter le python alors que j'étais habitué jusqu'ici à des langages comme le C++ ou le Java et j'aimerai bien pouvoir faire ce qui se fait très bien sous ces langages en python à savoir des classes abstraites et des fonctions virtuelles pures. Voici l'exemple qui me bloque pour l'instant (écriture approximative et minimaliste) :

     
    class Tree{
    virtual int cost();
    }

    class Node : Tree{
    private:
    Tree s0;
    Tree s1;
    public:
    int cost(){
    return s0.cost() + s1.cost();}
    }

    class Leaf : Tree{
    public:
    int cost(){
    return 1;}
    }

    En python, je m'y prend sûrement comme un pied mais je n'arrive pas à typer la fonction cost et je ne trouve pas d'équivalent à ceci. Je lis partout qu'en python les classes abstraites ne posent pas de problème et que toutes les fonctions sont virtuelles mais concrètement comment ça marche ?
    Si quelqu'un par hasard connait un équivalent de ce bout de code en python ?

    Merci pour votre aide.
    • Re: Comment faire des fonctions virtuelles et des classes abstraites proprement en python

      Envoyé par tarek le 8 Novembre 2005 à 20:36
      Salut,

      en python toutes les méthodes sont virtuelles de base.

      toutes les méthodes sont publics, sauf si elles sont préfixées par '__'.

      Il n'y a pas non plus de typage statique.

      de plus il faut construire les attributs dans les constructeurs (__init__) des classes sinon c'est des variables de classe communes à toutes les instances.

      l'instance est 'self', à chaque aopel (comme this en java)

      un méthode virtuelle pure, ca n'existe pas, à la place on
      lève une exception particulière.

      pour ton exemple ca peut donner:


      class Tree:
      def cost(self):
      raise NotImplementedError


      class Node(Tree):
      def __init__(self):
      self.__s0 = Tree()
      self.__s1 = Tree()

      def cost(self):
      return self.__s0.cost() + self.__s1.cost()

      class Leaf(Tree):
      def cost(self):
      return 1

    • Re: Comment faire des fonctions virtuelles et des classes abstraites proprement en python

      Envoyé par tarek le 8 Novembre 2005 à 20:38
      heu sauf que


      self.__s0 = Tree()
      self.__s1 = Tree()


      doit etre remplacé par une insanciation de la classe concrète ici bien sur.
    • Re: Comment faire des fonctions virtuelles et des classes abstraites proprement en python

      Envoyé par figo le 9 Novembre 2005 à 00:34
      Merci, j'avoue c'est beaucoup plus propre que ce que j'avait fait,
      juste deux questions :
      * le coup des __ c'est juste une convention ou c'est repris dans l'interpréteur ?
      * quand tu dis une classe concrète tu entends quoi, parce que justement ce que je comptais mettre ce serait (désolé pour le langage) :

      Node( Tree s0_0, Tree s1_0 ){
      s0 = s0_0;
      s1 = s1_0;
      }

      où toutes les classes sont abstraites.
      Mais en python je ne vois pas comment faire sans typer. En fait tout l'intérêt des classes dérivées c'est de pouvoir laisser du flou dans le type, donc j'imagine que c'est faisable en python sans y faire de référence à une classe concrète. Enfin bref je ne vois pas comment faire...

      Merci d'avance
    • Re: Comment faire des fonctions virtuelles et des classes abstraites proprement en python

      Envoyé par figo le 9 Novembre 2005 à 00:35
      Merci, j'avoue c'est beaucoup plus propre que ce que j'avait fait,
      juste deux questions :
      * le coup des __ c'est juste une convention ou c'est repris dans l'interpréteur ?
      * quand tu dis une classe concrète tu entends quoi, parce que justement ce que je comptais mettre ce serait (désolé pour le langage) :

      Node( Tree s0_0, Tree s1_0 ){
      s0 = s0_0;
      s1 = s1_0;
      }

      où toutes les classes sont abstraites.
      Mais en python je ne vois pas comment faire sans typer. En fait tout l'intérêt des classes dérivées c'est de pouvoir laisser du flou dans le type, donc j'imagine que c'est faisable en python sans y faire de référence à une classe concrète. Enfin bref je ne vois pas comment faire...

      Merci d'avance
    • Re: Comment faire des fonctions virtuelles et des classes abstraites proprement en python

      Envoyé par tarek le 9 Novembre 2005 à 01:09
      les __ ca fait partie du langage, objet.__s0 ne peut pas être accédé.

      Il n'y a pas de typage statique en Python.
      Donc le flou dans le type, c'est que ta variable n'existe pas avant de l'affecter ;)



      class Node(Tree):
      def __init__(self, element0, element1):
      self.__s0 = element0
      self.__s1 = element1

      def cost(self):
      return self.__s0.cost() + self.__s1.cost()



      affectation:


      >>> s0 = Leaf()
      >>> s1 = Leaf()
      >>> noeud = Node(s0, s1)
      >>> noeud.cost()
      2

    • Re: Comment faire des fonctions virtuelles et des classes abstraites proprement en python

      Envoyé par neonox le 3 Février 2006 à 00:58
      petites precisions :
      les objects commencant pas __ peuvent être accessible.

      exemple :


      class A:
      __var=1
      def SetVar(self,var):
      self.__var=var
      def GetVar(self):
      return self.__var

      a=A()
      a.SetVar(3)
      print a.GetVar()
      print a._A__var
      a._A__var='coucou'


      c moins accessible, mais si l'on connait le nom de la classe on peut acceder en lecture et en ecriture a l'objet

      a l'interieur de la classe, l'objet ne change pas de nom

      a l'exterieur on doit rajouter devant _ puis le nom de la classe
    • Re: Comment faire des fonctions virtuelles et des classes abstraites proprement en python

      Envoyé par tarek le 3 Février 2006 à 14:50
      oui c'est une protection toute relative.

      Tu peux toujours retrouver les valeurs en fouillant dans le __dict__,
      mais si le développeur éprouve ce besoin de "tricher", c'est que cette propriété
      n'est peut être pas privée en terme d'archi
Rendu par Ploneboard