При реализации классов, которые используются как в синхронных, так и в асинхронных приложениях, я обнаруживаю, что поддерживаю практически идентичный код для обоих вариантов использования.
Просто в качестве примера рассмотрим:
from time import sleep
import asyncio
class UselessExample:
def __init__(self, delay):
self.delay = delay
async def a_ticker(self, to):
for i in range(to):
yield i
await asyncio.sleep(self.delay)
def ticker(self, to):
for i in range(to):
yield i
sleep(self.delay)
def func(ue):
for value in ue.ticker(5):
print(value)
async def a_func(ue):
async for value in ue.a_ticker(5):
print(value)
def main():
ue = UselessExample(1)
func(ue)
loop = asyncio.get_event_loop()
loop.run_until_complete(a_func(ue))
if __name__ == '__main__':
main()
В этом примере это не так уж и плохо, методы ticker
UselessExample
легко поддерживать в тандеме, но вы можете себе представить, что обработка исключений и более сложные функциональные возможности могут быстро расширить метод и сделать его более проблематичным, даже если оба метода могут остаются практически идентичными (заменяются только некоторые элементы их асинхронными аналогами).
Если предположить, что нет существенной разницы, которая делает целесообразным полное их внедрение, каков наилучший (и наиболее питонский) способ поддерживать такой класс и избегать ненужного дублирования?