2016-04-17 14 views
6

tôi có thừa kế sau:Python làm thế nào để biến một kết quả của một phương pháp vào máy phát điện

class Processor(object): 
    def get_listings(self): 
     """ 
     returns a list of data 
     """ 
     raise NotImplemented() 

    def run(self): 
     for listing in get_listings(): 
      do_stuff(listing) 

class DBProcessor(Processor): 
    def get_listings(self): 
     """ 
     return a large set of paginated data 
     """ 
     ... 
     for page in pages: 
      for data in db.fetch_from_query(...): 
       yield data 

Mặc dù công trình này, điều này không thành công trên len(self.get_listings()) hoặc bất kỳ danh sách các hoạt động khác.

Câu hỏi của tôi là làm cách nào để cấu trúc lại mã của mình mà DBProcessor.get_listings có thể xử lý các hoạt động danh sách, mà còn khi trình lặp của nó được gọi là nó sẽ trả về một trình tạo?

Trả lời

0

Tùy thuộc vào hoạt động của list mà bạn muốn hỗ trợ. Một số người trong số họ sẽ chỉ chỉ tiêu thụ máy phát khi đặt mặc định thành iter.

Nếu bạn biết kết quả của các hoạt động (ví dụ len) trước bạn chỉ có thể bỏ qua nó bằng cách tạo ra một GeneratorContainer:

class GeneratorContainer(): 
    def __init__(self, generator, length): 
     self.generator = generator 
     self.length = length 

    def __iter__(self): 
     return self.generator 

    def __len__(self): 
     return self.length 

result = GeneratorContainer(DBProcessor().get_listings(), length) 
# But you need to know the length-value. 

Calling len sau đó sẽ không cố gắng để lặp qua các máy phát điện. Nhưng bạn có thể luôn luôn chỉ cần tạo một danh sách để các dữ liệu sẽ không bị cạn kiệt:

result = list(DBProcessor().get_listings()) 

và sử dụng nó như là một danh sách mà không có lợi thế phát và bất lợi.

+0

Tôi không downvote ... –

4

Tôi nghĩ rằng tôi có một ý tưởng:

class DBListings(object): 
    def __iter__(self): 
     for page in pages: 
      for data in db.fetch_from_query(...): 
       yield data 

    def __len__(self): 
     return db.get_total_from_query(...) 
     """ 
     Or the following 
     counter = 0 
     for x in self: 
      counter += 1 
     return counter 
     """ 

class DBProcessor(Processor): 
    def get_listings(self): 
     """ 
     return a large set of paginated data 
     """ 
     return DBListings() 

CẬP NHẬT: Chỉ cần kiểm tra mã trên, hoạt động.

+0

'sum (1 _ trong tự) 'sẽ làm tương tự. 'Db.fetch_from_query' trở lại là gì? –

+0

trả về danh sách các hàng từ cơ sở dữ liệu –

0

Nếu bạn muốn chuyển đổi máy phát điện (iterator trong phi Python nói) được sản xuất bởi get_listings vào một danh sách, bạn chỉ cần sử dụng

listings = list(get_listings()) 
Các vấn đề liên quan