2009-07-22 11 views
109

Mam klasy jak następuje:Python: dostęp klasa nieruchomość z ciągiem

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

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

Chcę przekazać ciąg dla zmiennej źródłowej w doSomething i uzyskać dostęp do elementu klasy o tej samej nazwie.

Próbowałem getattr który działa tylko na funkcjach (z tego co mogę powiedzieć), a także mając User przedłużyć dict i korzystania self.__getitem__, ale to nie działa. Jaki jest najlepszy sposób na zrobienie tego?

Odpowiedz

173

x = getattr(self, source) będzie działał idealnie, jeśli source nazwie dowolny atrybut własny, w tym other_data w twoim przykładzie.

+0

(realizując to stara gwintu). Byłem zdezorientowany/zawsze zapominam o tym z powodu dyktatury. Jeśli chcę uzyskać wartość z dyktowania, mogę powiedzieć: myDict.get ('keyy'), więc oczekiwałbym, że atrybuty będą działać w ten sam sposób: myObject.getattr ('attr_name'). Ale zamiast tego biorą obiekt jako pierwszy argument ... dobrze, ale widoczna niekonsekwencja jest powodem, dla którego miałem kłopoty. –

4

Rozszerzanie odpowiedź Alexa nieznacznie:

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") 

przyniesie:

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

Jednak osobiście nie sądzę, że to świetny styl - getattr pozwoli Ci uzyskać dostęp do dowolnego atrybutu instancji, w tym takie rzeczy jak sama metoda, lub nawet __dict__ instancji. Proponuję, żeby zamiast wdrożyć słownika źródeł danych, tak jak poniżej:

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") 

ponownie otrzymując:

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

+0

Nie wyjaśniłem poprawnie ... moich przeprosin. Jestem w stanie uzyskać dane za pośrednictwem łańcucha. Mam jednak problemy z ustawianiem danych przy użyciu powyższych metod. zwłaszcza te próbowali getattr (samo "other_data") = [1, 2, 3] jak siebie .__ setitem __ ("other_data" [1, 2, 3]) – sberry

+0

@ sberry2A 'getattr() 'służy tylko do uzyskiwania,' setattr() 'służy do ustawiania. Nie można przypisać do wartości zwracanej z 'getattr()'. – smci

124

obrazek jest wart tysiąca słów:

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

Podoba mi się ta odpowiedź w szczególności, ponieważ ilustruje ona po prostu, że funkcja getattr() działa również poza metodami klasy. – Eric

18
  • getattr(x, 'y') jest równoważne z x.y
  • setattr(x, 'y', v) odpowiada x.y = v
  • delattr(x, 'y') odpowiada del x.y
+0

Jak mogę uzyskać dostęp do 'x.y' zgodnie z łańcuchem wartości' v'? – user2284570

+0

@ user2284570: Jeśli 'v' zawiera ciąg' 'y'', to' getattr (x, v) 'podaje wartość' x.y'. – md2perpe

+0

@ md2perpe, ale tak nie jest. – user2284570