2015-01-23 6 views
7

निष्पादित करने की सूची में जोड़ें, मुझे एक फ़ंक्शन download_all मिला है जो अनुक्रम में उन्हें डाउनलोड करने के लिए पृष्ठों की हार्डकोडेड सूची के माध्यम से पुनरावृत्त करता है। लेकिन अगर मैं किसी पृष्ठ के परिणामों के आधार पर सूची में गतिशील रूप से जोड़ना चाहता हूं, तो मैं इसे कैसे कर सकता हूं? उदाहरण के लिए पहला पृष्ठ डाउनलोड करें, इसे पार्स करें, और परिणामों के आधार पर दूसरों को ईवेंट लूप में जोड़ें।गतिशील रूप से पाइथन एसिंसिओ के इवेंट लूप को

@asyncio.coroutine 
def download_all(): 
    first_page = 1 
    last_page = 100 
    download_list = [download(page_number) for page_number in range(first_page, last_page)] 
    gen = asyncio.wait(download_list) 
    return gen 

if __name__ == '__main__': 
    loop = asyncio.get_event_loop() 
    futures = loop.run_until_complete(download_all()) 

उत्तर

1

कृपया Web Crawler example पर एक नज़र डालें।

यह asyncio.JoinableQueue कतार का उपयोग कार्य कार्यों के लिए यूआरएल संग्रहीत करने के लिए करता है, लेकिन बहुत उपयोगी तकनीकों का भी प्रदर्शन करता है।

+2

यह अच्छा होगा यदि आप एक वास्तविक उदाहरण यहाँ और फिर यह एक संदर्भित दिया होगा। – KronoS

+0

उदाहरण सामान्य से अधिक बड़ा है। मुझे संदेह है कि यहां धक्का दिया जाना चाहिए। –

2

इसे पूरा करने का एक तरीका एक कतार का उपयोग कर है।

#!/usr/bin/python3 

import asyncio 

try: 
    # python 3.4 
    from asyncio import JoinableQueue as Queue 
except: 
    # python 3.5 
    from asyncio import Queue 

@asyncio.coroutine 
def do_work(task_name, work_queue): 
    while not work_queue.empty(): 
     queue_item = work_queue.get_nowait() 

     # simulate condition where task is added dynamically 
     if queue_item % 2 != 0: 
      work_queue.put_nowait(2) 
      print('Added additional item to queue') 

     print('{0} got item: {1}'.format(task_name, queue_item)) 
     yield from asyncio.sleep(queue_item) 
     print('{0} finished processing item: {1}'.format(task_name, queue_item)) 

if __name__ == '__main__': 

    queue = Queue() 

    # Load initial jobs into queue 
    [queue.put_nowait(x) for x in range(1, 6)] 

    # use 3 workers to consume tasks 
    taskers = [ 
     do_work('task1', queue), 
     do_work('task2', queue), 
     do_work('task3', queue) 
    ] 

    loop = asyncio.get_event_loop() 
    loop.run_until_complete(asyncio.wait(taskers)) 
    loop.close() 

आप asyncio से एक कतार का उपयोग सुनिश्चित कर सकते हैं कि काम की "इकाइयों" कार्य/वायदा है कि शुरू में asyncio की घटना पाश को दिया जाता है से अलग हैं। असल में यह कुछ शर्त दिए गए काम के अतिरिक्त "इकाइयों" को जोड़ने के लिए अनुमति देता है।

ध्यान दें कि ऊपर दिए गए उदाहरण में भी क्रमांकित कार्य टर्मिनल हैं इसलिए यदि ऐसा है तो एक अतिरिक्त कार्य नहीं जोड़ा जाता है। यह अंततः सभी कार्यों को पूरा करने के परिणामस्वरूप होता है, लेकिन आपके मामले में आप यह निर्धारित करने के लिए आसानी से किसी अन्य शर्त का उपयोग कर सकते हैं कि कतार में कोई अन्य आइटम जोड़ा गया है या नहीं।

आउटपुट:

Added additional item to queue 
task2 got item: 1 
task1 got item: 2 
Added additional item to queue 
task3 got item: 3 
task2 finished processing item: 1 
task2 got item: 4 
task1 finished processing item: 2 
Added additional item to queue 
task1 got item: 5 
task3 finished processing item: 3 
task3 got item: 2 
task3 finished processing item: 2 
task3 got item: 2 
task2 finished processing item: 4 
task2 got item: 2 
task1 finished processing item: 5 
task3 finished processing item: 2 
task2 finished processing item: 2 
+0

इस मामले में 'asyncio.Queue' का उपयोग करने की कोई आवश्यकता नहीं है, क्योंकि आप इसके कोरआउट तरीकों का उपयोग नहीं कर रहे हैं। सामान्य 'सूची' करेगा: https://gist.github.com/452f9a9f385e1d839309f76bb421ae3c – azag0

संबंधित मुद्दे