2009-07-22 14 views
109

Ho una classe come la seguente:Python: l'accesso alle proprietà classe da stringa

class User: 
    def __init__(self): 
     self.data = [] 
     self.other_data = [] 

    def doSomething(self, source): 
     // if source = 'other_data' how to access self.other_data 

voglio passare una stringa per la variabile sorgente in doSomething e accedere al membro della classe con lo stesso nome.

ho cercato getattr che funziona solo sulle funzioni (da quello che posso dire), oltre ad avere User estendono dict e utilizzando self.__getitem__, ma che non funziona nemmeno. Qual è il modo migliore per farlo?

risposta

173

x = getattr(self, source) funzionerà perfettamente solo se source identifica QUALSIASI attributo di sé, incluso lo other_data nell'esempio.

+0

(realizzando questo è un vecchio filo). Ero confuso/dimentico sempre questo a causa di dicts. Se voglio ottenere un valore da un dict, posso dire: myDict.get ('keyy'), quindi mi aspetto che gli attributi funzionino allo stesso modo: myObject.getattr ('attr_name'). Ma invece prendono l'oggetto come primo argomento ... ok, ma l'apparente incoerenza è il motivo per cui ho avuto problemi. –

4

Estendere la risposta di Alex un po ':

class User: 
    def __init__(self): 
     self.data = [1,2,3] 
     self.other_data = [4,5,6] 
    def doSomething(self, source): 
     dataSource = getattr(self,source) 
     return dataSource 

A = User() 
print A.doSomething("data") 
print A.doSomething("other_data") 

sarà resa:

 
[1, 2, 3] 
[4, 5, 6] 

Tuttavia, personalmente non credo che sia grande stile - getattr vi permetterà di accedere a qualsiasi attributo dell'istanza, comprese le cose come il metodo doSomething o anche lo __dict__ dell'istanza. Vorrei suggerire che invece di implementare un dizionario di fonti di dati, in questo modo:

class User: 
    def __init__(self): 

     self.data_sources = { 
      "data": [1,2,3], 
      "other_data":[4,5,6], 
     } 

    def doSomething(self, source): 
     dataSource = self.data_sources[source] 
     return dataSource 

A = User() 

print A.doSomething("data") 
print A.doSomething("other_data") 

nuovo cedimento:

 
[1, 2, 3] 
[4, 5, 6] 

+0

Non ho spiegato correttamente ... le mie scuse. Sono in grado di ottenere i dati tramite la stringa. Tuttavia, sto riscontrando problemi nell'impostare i dati usando i metodi precedenti. Specificamente Ho provato getattr (self, "other_data") = [1, 2, 3] nonché self .__ setitem __ ("other_data", [1, 2, 3]) – sberry

+0

@ sberry2A, 'getattr() 'è solo per ottenere,' setattr() 'è per l'impostazione. Non puoi assegnare il valore di ritorno da 'getattr()'. – smci

124

di un'immagine vale più di mille parole:

>>> class c: 
     pass 
o = c() 
>>> setattr(o, "foo", "bar") 
>>> o.foo 
'bar' 
>>> getattr(o, "foo") 
'bar' 
+0

Mi piace questa risposta in particolare perché illustra, semplicemente, che la funzione getattr() funziona anche al di fuori dei metodi di classe. – Eric

18
  • getattr(x, 'y') è equivalente a x.y
  • setattr(x, 'y', v) è equivalente a x.y = v
  • delattr(x, 'y') equivale a del x.y
+0

Come posso accedere a 'x.y' in base alla stringa di valori di' v'? – user2284570

+0

@ user2284570: Se 'v' contiene la stringa' 'y'' quindi 'getattr (x, v)' fornisce il valore di 'x.y'. – md2perpe

+0

@ md2perpe tranne che non è il caso. – user2284570

Problemi correlati