2009-07-22 37 views
109

lớp tôi có một lớp học như sau:Python: Truy cập tài sản từ chuỗi

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

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

Tôi muốn vượt qua một chuỗi cho biến nguồn trong doSomething và truy cập các thành viên lớp cùng tên.

Tôi đã thử getattr chỉ hoạt động trên các chức năng (từ những gì tôi có thể biết) cũng như có User mở rộng dict và sử dụng self.__getitem__, nhưng điều đó không hoạt động. Cách tốt nhất để làm việc này là gì?

Trả lời

173

x = getattr(self, source) sẽ hoạt động hoàn toàn nếu source tên MỌI thuộc tính của bản thân, bao gồm other_data trong ví dụ của bạn.

+0

(nhận ra đây là một chủ đề cũ). Tôi đã bối rối/luôn luôn quên điều này vì các dicts. Nếu tôi muốn nhận được một giá trị từ một dict, tôi có thể nói: myDict.get ('keyy'), vì vậy tôi mong đợi các thuộc tính hoạt động theo cùng một cách: myObject.getattr ('attr_name'). Nhưng thay vào đó họ lấy đối tượng làm đối số đầu tiên ... ok để làm, nhưng sự mâu thuẫn rõ ràng là lý do tại sao tôi gặp rắc rối. –

4

Mở rộng câu trả lời của Alex hơi:

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

sẽ mang lại:

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

Tuy nhiên, cá nhân tôi không nghĩ rằng đó là phong cách tuyệt vời - getattr sẽ cho phép bạn truy cập vào bất kỳ thuộc tính của các ví dụ, bao gồm những thứ như chính phương thức doSomething hoặc thậm chí là __dict__ của cá thể. Tôi sẽ đề nghị rằng thay vào đó bạn thực hiện một cuốn từ điển các nguồn dữ liệu, như vậy:

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

lại năng suất:

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

+0

Tôi không giải thích đúng ... lời xin lỗi của tôi. Tôi có thể lấy dữ liệu qua chuỗi. Tuy nhiên, tôi đang gặp sự cố khi thiết lập dữ liệu bằng các phương pháp trên. Cụ thể là tôi đã cố gắng getattr (bản thân, "other_data") = [1, 2, 3] cũng như tự .__ SetItem __ ("other_data", [1, 2, 3]) – sberry

+0

@ sberry2A, 'getattr() 'chỉ để nhận,' setattr() 'là để thiết lập. Bạn không thể gán giá trị trả về từ 'getattr()'. – smci

124

Một bức ảnh đáng giá ngàn lời:

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

Tôi thích câu trả lời này đặc biệt bởi vì nó minh họa, đơn giản, hàm getattr() cũng hoạt động bên ngoài các phương thức lớp. – Eric

18
  • getattr(x, 'y') tương đương với x.y
  • setattr(x, 'y', v) tương đương với x.y = v
  • delattr(x, 'y') tương đương với del x.y
+0

Làm cách nào tôi có thể truy cập 'x.y' theo chuỗi giá trị' v'? – user2284570

+0

@ user2284570: Nếu 'v' chứa chuỗi' 'y'' thì 'getattr (x, v)' cho giá trị 'x.y'. – md2perpe

+0

@ md2perpe ngoại trừ nó không phải là trường hợp. – user2284570

Các vấn đề liên quan