2012-06-09 28 views
7

Có thể quá tải [] (__getitem__) Phương thức chuỗi và toán tử Python bằng cách sử dụng tham chiếu bộ nhớ ban đầu.Quá tải [] toán tử python và các phương thức chuỗi sử dụng tham chiếu bộ nhớ

Hãy tưởng tượng tôi có một lớp Math chấp nhận một danh sách các số nguyên, như thế này:

class Math(object): 
    def __init__(self, *args, **kwargs): 
     assert(all([isinstance(item, int) for item in list(args)])) 
     self.list = list(args) 

    def add_one(self): 
     for index in range(len(self.list)): 
      self.list[index] += 1 

Và tôi muốn làm một cái gì đó như thế này:

instance = Math(1,2,3,4,5) 
instance[2:4].add_one() 

Sau khi thực thi mã này instance.list nên là [1,2,4,5,5], điều này có khả thi không?

Tôi biết tôi có thể làm điều gì đó như add_one(2,4), nhưng đây không phải là kiểu API tôi muốn có nếu có thể.

Cảm ơn

Trả lời

9

Như Winston đề cập, bạn cần phải thực hiện một đối tượng phụ trợ:

class Math(object): 
    def __init__(self, *args, **kwargs): 
     self.list = list(args) 

    def __getitem__(self, i): 
     return MathSlice(self, i) 

class MathSlice(object): 
    def __init__(self, math, slice): 
     self.math = math 
     self.slice = slice 

    def add_one(self): 
     for i in xrange(*self.slice.indices(len(self.math.list))): 
      self.math.list[i] += 1 


instance = Math(1,2,3,4,5) 
instance[2:4].add_one() 

print instance.list 

Làm thế nào bạn chia sẻ các đối tượng toán học với đối tượng MathSlice phụ thuộc vào những gì bạn muốn ngữ nghĩa là nếu những thay đổi đối tượng toán học.

+0

'xrange (* self.slice.indices (len (self.math.list))) 'cảm thấy hết sức vô lý. Có cách nào tốt hơn? – Eric

+0

Ngoài ra, bạn đang trộn 'self.fields' và' self.list' – Eric

+0

@Eric: Tôi đã xóa Math.add_one không cần thiết, và vâng rằng xrange (* ...) có vẻ hơi rườm rà, nhưng tôi không biết một cách ngắn hơn. –

5

Numpy thực hiện điều gì đó tương tự.

Phương thức __getitem__ sẽ nhận đối tượng slice. Xem http://docs.python.org/reference/datamodel.html để biết chi tiết. Bạn sẽ cần trả về một đối tượng mới, nhưng thực hiện đối tượng đó sao cho nó sửa đổi danh sách gốc.

+0

Cảm ơn Winston đã trả lời. Tôi chấp nhận câu trả lời của Ned, bởi vì anh ấy đưa ra nhiều chi tiết triển khai hơn và tôi nghĩ những người dùng khác sẽ thấy nó hữu ích hơn. Nhưng tôi đánh giá cao câu trả lời của bạn. – maraujop

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