2015-06-11 3 views
5

Potrebbe essere una domanda molto semplice ma sono molto confuso con dove sto andando adesso. Qui è una classe molto semplice:L'oggetto non ha attributo '__getitem__' (istanza di classe?)

class Book(object): 
    def __init__(self, title, price): 
     self.book = {'title':title, 'price':price} 

E quando faccio funzionare questo:

book = Book('foo', 300) 
book['price'] 

Sputa:

TypeError: 'Book' object has no attribute '__getitem__' 

So che non è il modo convenzionale di inizializzazione di un'istanza dal momento che sto usando un dizionario. Ma mi chiedo perché quel codice sputa un errore TypeError. Come faccio a risolvere questo problema? Grazie in anticipo.

ps. Il tipo di istanza del libro è di classe?

risposta

11

È perché una classe non è un oggetto dict. L'accesso alle proprietà su un'istanza di una classe viene eseguito tramite l'operatore punto.

book.book['price'] 
>> 300 

Se si desidera accedere alle chiavi all'interno del vostro dict direttamente sulla tua istanza di classe si dovrà implementare il metodo __getitem__ sulla vostra classe.

def __getitem__(self, key): 
    return self.book[key] 

book['price'] 
>> 300 
5

Sì. Il libro è un oggetto della classe Prenota perché l'hai inizializzato in quel modo.

book = Book('foo', 300) 
book['price'] 

Provate

print book.book['price']

Così si desidera accedere a un dizionario chiamato libro di un oggetto fa riferimento come libro e si desidera estrarre il valore di prezzo dal dizionario .

In genere l'operatore [] cerca il metodo __getitem__() e passa la chiave richiesta come argomento. Łukasz R. ha mostrato come farlo. I dizionari eseguono una ricerca chiave mentre gli array trovano la sezione o l'indice.

è spiegato in dettaglio qui: https://docs.python.org/2/reference/datamodel.html

Ora perché si sta creando una classe qui, perché si vuole creare un dizionario separato per nativo must have attributi della classe. Creare attributi come il seguente esempio:

class Book(object): 
    def __init__(self, title, price): 
     self.title = 'foo' 
     self.price = 300 

book = Book('foo', 300) 
print book.title 
3

book.book['price'] funzionerebbe. Per accedere al membro proxy devi implementare il metodo magico __getitem__.

class Book(object): 
    def __init__(self, title, price): 
     self.book = {'title':title, 'price':price} 
    def __getitem__(self, item): 
     return self.book[item] 
1
class Book(object): 
    def __init__(self, title, price): 
     self.book = {'title':title, 'price':price}    

book = Book('foo', 300) 
print book.book['price']