2016-03-20 14 views
1

從維基百科解析數據需要很長時間,這是無法接受的。我想做的,而不是一個線程\進程,至少5.谷歌搜索後,我發現在Python 3.5中有async for需要幫助以製作「循環」的異步版本

下面是當前「同步」代碼的「非常短」版本,以顯示整個過程(帶有註釋以快速理解代碼的作用)。

def update_data(region_id=None, country__inst=None, upper_region__inst=None): 
    all_ids = [] 

    # Get data about countries or regions or subregions 
    countries_or_regions_dict = OSM().get_countries_or_regions(region_id) 

    # Loop that I want to make async 
    for osm_id in countries_or_regions_dict: 
     names = countries_or_regions_dict[osm_id]['names'] 

     if 'wiki_uri' in countries_or_regions_dict[osm_id]: 
      wiki_uri = countries_or_regions_dict[osm_id]['wiki_uri'] 

      # PARSER: From Wikipedia gets translations of countries or regions or subregions 
      translated_names = Wiki().get_translations(wiki_uri, osm_id) 

      if not region_id: # Means it is country 
       country__inst = Countries.objects.update_or_create(osm_id=osm_id, 
                    defaults={**countries_regions_dict[osm_id]})[0] 

      else: # Means it is region\subregion (in case of recursion) 
       upper_region__inst = Regions.objects.update_or_create(osm_id=osm_id, 
                     country=country__inst, 
                     region=upper_region__inst, 
                     defaults={**countries_regions_dict[osm_id]})[0] 
      # Add to DB translated names from wiki 
      for lang_code in names: 
       ### 

      # RECURSION: If country has regions or region has subregions, start recursion 
      if 'divisions' in countries_or_regions_dict[osm_id]: 
       regions_list = countries_or_regions_dict[osm_id]['divisions'] 

       for division_id in regions_list: 
        all_regions_osm_ids = update_osm(region_id=division_id, country__inst=country__inst, 
                   upper_region__inst=upper_region__inst) 

        all_ids += all_regions_osm_ids 

    return all_ids 

我意識到我需要改變def update_dataasync def update_data並相應for osm_id in countries_or_regions_dictasync for osm_id in countries_or_regions_dict

,但我找不到的信息是否有必要在我的情況和使用get_event_loop()?和how \在哪裏指定可以同時運行多少次循環迭代?有人可以幫我請使loop for異步嗎?

回答

0

asyncio模塊不會創建多個線程/進程,它在一個線程,一個進程中運行代碼,但可以處理I/O塊(如果您編寫代碼的方式)的情況。 Read,當你應該使用asyncio

只要您的代碼具有同步性質,我會建議使用線程而不是asyncio。創建ThreadPoolExecutor並使用它在多個線程中解析Wiki。

+0

你的文章推動我閱讀很多:)現在我看到,asyncio在一個線程\進程中執行所有操作。你能澄清幾件事嗎? 1)ThreadPoolExecutor(TPE)可以啓動不同的線程,但只有一個線程可以在給定的時間使用,所以它類似於asyncio。我對嗎? 2)在我的情況下,我可以使用這兩種方法(因爲都解決IO綁定的問題,在我的情況下'解析'),但TPE更容易,因爲只需要少量的代碼更改? – TitanFighter

+0

3)方法'get_translations'使用'請求'。如果'請求'需要資源來下載頁面,並且TPE只使用一個線程,那麼優勢在哪? IO操作的執行超出了線程的範圍嗎? – TitanFighter

+0

@TitanFighter,1)是2)是的3)你應該在線程執行器中運行多個'get_translations'。 TPE將使用多個線程。儘管只有其中一個可以在時間運行,但只要它面臨I/O操作,它就會將控制轉移到另一個線程,而不是在I/O完成時浪費時間等待。發生這種情況是因爲網絡I/O操作本身是異步的。閱讀以下有關I/O的鏈接:http://stackoverflow.com/a/16528847/1113207您還可以閱讀本文中的代碼示例(特別是「入門」和以下):http://chriskiehl.com/article/並行功能於一身的行/ –