從維基百科解析數據需要很長時間,這是無法接受的。我想做的,而不是一個線程\進程,至少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_data
到async def update_data
並相應for osm_id in countries_or_regions_dict
到async for osm_id in countries_or_regions_dict
,
,但我找不到的信息是否有必要在我的情況和使用get_event_loop()
?和how \在哪裏指定可以同時運行多少次循環迭代?有人可以幫我請使loop for
異步嗎?
你的文章推動我閱讀很多:)現在我看到,asyncio在一個線程\進程中執行所有操作。你能澄清幾件事嗎? 1)ThreadPoolExecutor(TPE)可以啓動不同的線程,但只有一個線程可以在給定的時間使用,所以它類似於asyncio。我對嗎? 2)在我的情況下,我可以使用這兩種方法(因爲都解決IO綁定的問題,在我的情況下'解析'),但TPE更容易,因爲只需要少量的代碼更改? – TitanFighter
3)方法'get_translations'使用'請求'。如果'請求'需要資源來下載頁面,並且TPE只使用一個線程,那麼優勢在哪? IO操作的執行超出了線程的範圍嗎? – TitanFighter
@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/並行功能於一身的行/ –