Erreur python 3.11 Programmation Objet

Fermé
haleyy1717 - Modifié le 17 mars 2023 à 16:34
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 - 17 mars 2023 à 16:46

Bonjour,

J'ai défini une classe nommée Pile dans un module nommé piles que j'ai importé dans un autre programme. Ce programme est censé résoudre des opérations écrites selon la notation polonaise inverse.

La partie du code en question est une fonction de la classe Pile qui permet d'empiler un élément sur l'objet Pile défini par cette classe. Voici la classe en question :

class Pile:
    """Classe définissant une structure de pile."""
    def __init__(self):
        self = []

    def contenu(self):
        return list(self)

    def creerPileVide():
        self.contenu = []

    def est_vide(self):
        """Renvoie le booléen True si la pile est vide, False sinon."""
        return self.contenu == []

    def empiler(self, v):
        """Place l'élément v au sommet de la pile"""
        self.append(v)

    def depiler(self):
        """
        Retire et renvoie l’élément placé au sommet de la pile,
        si la pile n’est pas vide.
        """
        if not self.est_vide():
            return self.contenu.pop()

    def hauteur(self):
        temp_list  = creer_pile_vide()
        height = 0
        while est_vide(self) == False:
            empiler(temp_list, depiler(self))
            height +=1
        while est_vide(temp_list) != False:
            empiler(self,depiler(temp_list))
        return height

    def maxi(self,i):
        Q=creer_pile_vide()
        n=1
        x=depiler(self)
        empiler(Q,x)
        maximum=x
        rang=1
        while not(est_vide(self)) and n<i:
            n=n+1
            x=depiler(self)
            empiler(Q,x)
            if x>maximum:
                maximum=x
                rang=n
        while not(est_vide(Q)):
            x=depiler(Q)
            empiler(self,x)
        return rang

    def retourner(self,i):
        j=creer_pile_vide()
        e=creer_pile_vide()
        for k in range(i):
            empiler(j,depiler(self))
        for o in range(i):
            empiler(e,depiler(j))
        for z in range(i):
            empiler(self,depiler(e))

    def tri(self):
        h = hauteur(self)
        while h != 0:
            maximum = maxi(self, i)
            retourner(self, maximum)
            retourner(self,i)
            h -= 1


En exécutant la partie du programme nécessitant d'empiler un élément, j'obtiens cette erreur :

AttributeError: 'function' object has no attribute 'append'

La fonction append n'est-elle pas censée être built-in dans Python 3.11? Aidez-moi svp!

Le programme utilisé est ici :

def eval_expression(tab):
    import piles
    p=piles.Pile
    for element in tab:
        if element != '+' and element != '*':
            p.empiler(p, element)
        else:
            if element == '+':
                resultat = p.depiler() + p.depiler()
                p.empiler(resultat)
            else:
                resultat = p.depiler() * p.depiler()
                p.empiler(resultat)
    return p.depiler()

avec cet appel :

eval_expression([2, 3, '*', 5, '+'])

La réponse attendue est donc :

11:'int'

3 réponses

Bonsoir, en python self dans une classe est une référence à l'objet.

Tu l'écrases par une liste dans l'__init__, déjà ça pose problème, puis tu refais le même genre d'erreur juste après.

def contenu(self):
    return list(self)

def creerPileVide():
    self.contenu = []

Tu écrases la méthode contenu par une liste.

Tu devrais revoir les bases des classes en python.

0

Cela reste tout même complexe pour faire un simple calcul que l'on peut faire en une 30aine de ligne, utiliser une classe Pile pour finalement n'être qu'un interface à une liste python n'a pas d'utilité.

class Operation:
    def __init__(self):
        self.pile = []
        self.resultat = 0
        self.operations = {
            '+':self.additionner,
            '*':self.multiplier,
        }

    def calculer(self, valeur):
        for element in valeur:
            if type(element) == int:
                self.pile.append(element)
            elif element in self.operations:
                self.operations[element]()
            else:
                raise ValueError(f'valeur {valeur} est invalide')
        return self.resultat

    def additionner(self):
        for v in self.pile:
            self.resultat += v
        self.pile.clear()

    def multiplier(self):
        n = self.pile[0]
        for v in self.pile[1:]:
            n *= v
        self.resultat += n
        self.pile.clear()


operation = Operation()
print(operation.calculer([2, 3, '*', 5, '+']))
0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
Modifié le 17 mars 2023 à 16:51

Bonjour,

Plusieurs suggestions :

  • Comme le dit figro, ton constructeur est incohérent. Une manière de résoudre ton problème serait de faire hériter Pile de list.
  • creerPileVide devrait être une méthode statique (cf décorateur @staticmethod).
  • les notations manquent de cohérence (tant maMethode, tantôt ma_methode)
  • si on omet l'aspect pédagogique, je suis un peu sceptique sur l'implémentation de certaines primitive de ta classe Pile qui, si on en a besoin, signifient probablement qu'on ne devrait pas utiliser une Pile mais une structure plus évoluée (par exemple une liste avec en tandem les fonction sorted et max)
  • ce qui est à gauche d'un point doit être un espace de nommage, une classe, ou une instance de classe. Or dans ton erreur, c'est une fonction.
  • Il existe des manières bien plus naturelles d'implémenter une pile en python (voir ce lien)
    • est_vide devient alors peu inutile : en python un ensemble vide correspond à faux dans un test. Si ta classe Pile hérite d'une de ces classes, alors tu peux parfaitement écrire :
      pile = Pile(...)
      
      ...
      
      if pile:
          print(f"Pile {pile} non vide")
      else:
          print(f"Pile {pile} vide")

Bonne chance

0