web-dev-qa-db-fra.com

Python débutant: AttributeError: l'objet 'list' n'a pas d'attribut

L'erreur dit:

AttributeError: 'list' object has no attribute 'cost' 

J'essaie d'obtenir un calcul de bénéfice simple en utilisant la classe suivante pour gérer un dictionnaire de bicyclettes:

class Bike(object):
    def __init__(self, name, weight, cost):
        self.name = name
        self.weight = weight
        self.cost = cost

bikes = {
    # Bike designed for children"
    "Trike": ["Trike", 20, 100],
    # Bike designed for everyone"
    "Kruzer": ["Kruzer", 50, 165]
    }

Lorsque j'essaie de calculer le profit avec mon instruction for, l'erreur d'attribut est générée.

# Markup of 20% on all sales
margin = .2
# Revenue minus cost after sale
for bike in bikes.values():
    profit = bike.cost * margin

Tout d’abord, je ne sais pas pourquoi il s’agit d’une liste, et tout semble être défini, non?

16
Charles Watson

Considérer:

class Bike(object):
    def __init__(self, name, weight, cost):
        self.name = name
        self.weight = weight
        self.cost = cost

bikes = {
    # Bike designed for children"
    "Trike": Bike("Trike", 20, 100),      # <--
    # Bike designed for everyone"
    "Kruzer": Bike("Kruzer", 50, 165),    # <--
    }

# Markup of 20% on all sales
margin = .2
# Revenue minus cost after sale
for bike in bikes.values():
    profit = bike.cost * margin
    print(profit)

Sortie:

 33,0 
 20.0 

La différence est que dans votre dictionnaire bikes, vous initialisez les valeurs sous forme de listes [...]. Au lieu de cela, il semble que le reste de votre code ait besoin de Bike instances. Donc, créez Bike instances: Bike(...).

Quant à ton erreur

AttributeError: 'list' object has no attribute 'cost'

cela se produira lorsque vous essayez d'appeler .cost sur un objet list. C'est assez simple, mais nous pouvons comprendre ce qui s'est passé en regardant où vous appelez .cost - dans cette ligne:

profit = bike.cost * margin

Cela indique qu'au moins un bike (c'est-à-dire qu'un membre de bikes.values() est une liste). Si vous regardez où vous avez défini bikes, vous pouvez voir que les valeurs étaient, en fait, des listes. Donc, cette erreur a un sens.

Mais puisque votre classe a un attribut cost, il semblait que vous essayiez d'utiliser Bike instances en tant que valeurs, j'ai donc apporté ce petit changement:

[...] -> Bike(...)

et vous êtes tous ensemble.

18
jedwards

Vous devez passer les valeurs du dict dans le constructeur Bike avant de l'utiliser de la sorte. Ou, voyez le namedtuple - semble plus en phase avec ce que vous essayez de faire.

4
mragh

Ce sont des listes parce que vous les tapez en tant que listes dans le dictionnaire:

bikes = {
    # Bike designed for children"
    "Trike": ["Trike", 20, 100],
    # Bike designed for everyone"
    "Kruzer": ["Kruzer", 50, 165]
    }

Vous devriez utiliser la classe de vélo à la place:

bikes = {
    # Bike designed for children"
    "Trike": Bike("Trike", 20, 100),
    # Bike designed for everyone"
    "Kruzer": Bike("Kruzer", 50, 165)
    }

Cela vous permettra d’obtenir le coût des vélos avec bike.cost comme vous le souhaitiez.

for bike in bikes.values():
    profit = bike.cost * margin
    print(bike.name + " : " + str(profit))

Cela va maintenant imprimer:

Kruzer : 33.0
Trike : 20.0
4
Ygedey