Как в Tornado создать экземпляр класса асинхронно?

Более менее разобрался(как мне кажется) с асинхронностью в торнадо, но при переписывании синхронного кода под торнадо возникла следующая проблема:
Во время обработки запросов создаются экземпляры различных объектов:
@gen.coroutine
def prepare(self):
	....
	obj = ObjClass()
	...

, при этом выполняются запросы в базу, которые хотелось бы выполнять асинхронно:
class ObjClass:
	def __init__(self):
		...
		db.find({...})
		...

Первое что пришло в голову - добавить во всех классах дополнительную инициализацию (если не вообще убрать __init__), в которую вынести все что требуется сделать асинхронным:
class ObjClass:
	def __init__(self):
		...

	@gen.coroutine
	def init(self):
		...
		db.find({...})
		...

@gen.coroutine
def prepare(self):
	....
	obj = yield ObjClass().init()
	...

Но хочется написать что-то вроде:
class ObjClass:
	@gen.coroutine
	def __init__(self):
		...
		yield db.find({...})
		...

@gen.coroutine
def prepare(self):
	....
	obj = yield ObjClass()
	...

Попытался покопать в сторону метаклассов и переопределения __call__, но выражение вроде
yield obj.__init__(*args, **kwargs)
не работает, поскольку __init__ в классе упорно не хочет становиться генератором с
class ObjClass:
	@gen.coroutine
	def __init__(self):
		...
		yield db.find({...})
		...

Есть какая-то скрытая магия в интерпретаторе, через которую не протащить корутину?
Как еще можно асинхронно создать экземпляр в Tornado?
  • Вопрос задан
  • 609 просмотров
Пригласить эксперта
Ответы на вопрос 2
un1t
@un1t
По всей видимости ты используешь какой-то синхронный код для работы с базой.
Надо использовать асинхронный драйвер для твоей базы для торнады.
Ответ написан
mututunus
@mututunus
Backend developer (Python, Golang)
__init__ ничего не возвращает и следовательно не может быть корутиной.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы