Я пишу программу, которая создает группу рабочих для асинхронного вызова API с использованием aiohttp
.Однако этот вопрос касается shared-объектов.Я предполагаю, что столкнулся бы с той же или подобной проблемой, если бы я был многопоточным.
У меня есть набор параметров URL-адресов по умолчанию, которые разделяют все работники, однако два значения этих параметров меняются от рабочего к рабочему:
DEFAULT_PARAMS = {
'q' : None, #<==CHANGES per worker
'offset' : '0', #<==CHANGES per worker
'mkt' : 'en-US', #<==STATIC for all workers
'moreParams' : '<most of the data>' #<==STATIC for all workers
}
Вот как я инициализирую свойWorker()
class:
class Worker(object):
def __init__(self, q):
# this copy iexpensive when > 100 workers.
self.initial_params = DEFAULT_PARAMS.copy()
# but witout copying entire default params dict, the next line
# would add alter the 'q' value for all instances of Worker.
self.initial_params.update({'q' : q})
Я ищу альтернативу вызову DEFAULT_PARAMS.copy()
для каждого нового работника, которого я создаю.
Выяснить, как поставить этот вопрос, было непросто,Я подозреваю, что мой ответ может лежать где-то в классе через атрибуты экземпляра.
Вот чрезвычайно простой пример моей программы:
import aiohttp
import asyncio
DEFUALT_PARAMS = {
'q' : None, #<==CHANGES per worker
'offset' : '0', #<==CHANGES per worker
'mkt' : 'en-US', #<==STATIC for all workers
'moreParams' : '<most of the data>' #<==STATIC for all workers
}
class Worker(object):
def __init__(self, q):
self.initial_params = DEFUALT_PARAMS.copy() # <==expensive
self.initial_params.update({'q' : q}) #<==without copying, overwrites ref for all classes.
async def call_api(self):
async with aiohttp.ClientSession() as sesh:
async with sesh.get(
'https://somesearchengine.com/search?',
params=self.initial_params
) as resp:
assert resp.status == 200
print(await resp.json())
async def main(workers, *, loop=None):
tasks = (asyncio.ensure_future(i.call_api(), loop=loop) for i in workers)
await asyncio.gather(*tasks)
if __name__ == "__main__":
loop = asyncio.get_event_loop()
queries = ['foo', 'bar', 'baz']
workers = (Worker(i) for i in queries)
loop.run_until_complete(main(workers, loop=loop))