2016-03-20 10 views
1

Wikipediaのデータを解析することは、受け入れがたいほどの時間がかかります。私は1つのスレッド\プロセスの代わりに、少なくとも5したいと思います。グーグル後、私はPython 3.5にはasync forがあることがわかりました。"loop 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 

は私がasync def update_dataからdef update_dataasync for osm_id in countries_or_regions_dictに応じfor osm_id in countries_or_regions_dict

を変更する必要があることに気づいたが、私は情報を見つけることができなかったかどうか、私の場合、どこにget_event_loop()を使用する必要がありますか?、 how \どこでループの反復回数を同時に指定できるか?誰かが私に助けてloop forを非同期にしてもらえますか?

答えて

0

asyncioモジュールは複数のスレッド/プロセスを作成せず、1つのスレッド、1つのプロセスでコードを実行しますが、I/Oブロック(コードを特別な方法で記述した場合)で状況を処理できます。 Readasyncioを使用する必要があります。

コードに同期性があるとすぐに、asyncioの代わりにスレッドを使用することをお勧めします。 ThreadPoolExecutorを作成し、それを使ってWikiを複数のスレッドで解析します。

+0

あなたの投稿は私にたくさんの読書を促しました:)今、asyncioはすべての処理を1つのスレッド\プロセスで行います。いくつかのことを明確にすることができますpls? 1)ThreadPoolExecutor(TPE)は異なるスレッドを開始できますが、同時に1つのスレッドしか使用できないため、asyncioと似ています。私は正しい? 2)そして私の場合は両方の方法を使用することができます(両方ともIOバインディングの問題を私の場合 '解析'で解決するため)。 – TitanFighter

+0

3)メソッド 'get_translations'は '要求'を使用します。 「要求」がページをダウンロードするためのリソースを必要とし、TPEがただ1つのスレッドを使用する場合、利点はどこにありますか? IO操作の実行がスレッドのスコープから外れていますか? – TitanFighter

+0

@TitanFighter、1)はい2)はい3)スレッドエグゼキュータで複数の 'get_translations'を実行する必要があります。 TPEは複数のスレッドを使用します。それらのうちの1つだけがI/O操作に直面するとすぐに実行できますが、I/Oが終了するまで待つ時間を無駄にするのではなく、別のスレッドに制御を移します。これは、ネットワークI/O操作が非同期であるために発生します。 I/Oについてのこのリンクを読む:http://stackoverflow.com/a/16528847/1113207この記事は、コード例(特に「はじめに」と以下)で読むこともできます:http://chriskiehl.com/article/ 1行/ –

関連する問題