2017-09-11 1 views
1

Je fais un exercice dans lequel vous êtes censé calculer une note de classy vos articles. Un tophat vous donne 2 points, un nœud papillon vous donne 4 points et un monocle vous donne 5 points. J'ai lancé un dictionnaire avec ces éléments sur chaque instance de classe, mais quand j'utilise getattr pour vérifier si l'élément a l'attribut, il retourne toujours None.La recherche de getattr échoue par exemple de la classe python

class Classy(object): 

    def __init__(self): 
     self.items = [] 
     self.classyItems = {'tophat': 2, 'bowtie': 4, 'monocle': 5} 

    def addItem(self, str): 
     self.items.append(str) 

    def getClassiness(self): 
     classiness = 0 
     for item in self.items: 
     itemIsClassy = getattr(self.classyItems, item, None) # Why does this always return none? 
     if itemIsClassy: 
      classiness += itemIsClassy 
     else: 
      pass 
     return classiness 


# Test cases 
me = Classy() 

# Should be 0 
print me.getClassiness() 

me.addItem("tophat") 
# Should be 2 
print me.getClassiness() # I'm getting 0 

Pourquoi getattrNone quand self.classyItems retournaient a clairement l'attribut de tophat?

Merci pour l'aide à tous! J'étais encore confus après avoir lu la réponse et simplement lu que les clés du dictionnaire ne sont pas des attributs ici m'a aidé. Is Python dict an Object?

+0

Vous pouvez utiliser la valeur par défaut dict 'self.classyItems.get (item, None)' – Vinny

Répondre

8

getattr accède à des attributs et/ou des méthodes, mais classyItems est une dict qui n'a pas de (visible) attribue et stocke son contenu sous forme de paires de valeurs clés .

Dans votre cas, vous devez utiliser dict.get au lieu de getattr, plus précisément self.classyItems.get(item, None), pour accéder aux valeurs par défaut. Cependant, les dictionnaires ont des méthodes accessibles à l'aide de getattr. C'est pourquoi vous y accédez en utilisant d[key] au lieu de d.key.

-1

Remplacer itemIsClassy = getattr(self.classyItems, item, None)-itemIsClassy = self.classyItems.get(item, None)

2

getattr() prend un objet et une chaîne de l'attribut à rechercher, et retourne que cet objet. Vous ne disposez pas d'un attribut nommé item dans votre objet, mais vous avez classyItems: En utilisant votre code, vous pouvez voir que:

>>> getattr(me, 'classyItems') 
{'bowtie': 4, 'tophat': 2, 'monocle': 5} 

Il est beaucoup plus facile (et lisible) à utiliser self.classyItems.get(item, None) qui recherche un dict et renvoie la valeur par défaut. Vous ne pouvez pas rechercher des valeurs de dict avec getattr, mais vous pouvez cependant vérifier si elle a certaines méthodes:

>>> getattr(me.classyItems, 'update') 
<built-in method update of dict object at 0x028ADE40> 
-1

Comme mentionné par @Dharmesh et @MSeifert, remplacez itemIsClassy = getattr(self.classyItems, item, None)-itemIsClassy = self.classyItems.get(item, None)

La raison pour laquelle votre le code n'a pas fonctionné n'est pas parce que classyItems n'a pas beaucoup d'attributs, c'est parce que la fonction getattr fonctionne sur les objets, pas le dictionnaire.