Чтобы между отдельными запусками можно было делать что-то другое полезное, можно добавить
асинхронность. В простейшем случае в Python 3.7+ это выглядит примерно так:
import asyncio
period = 2 # период в секундах
async def my_func():
print("Hello!")
async def periodic_func():
while True:
asyncio.create_task(my_func())
await asyncio.sleep(period)
if __name__ == "__main__":
try:
[asyncio.run](http://asyncio.run)(periodic_func())
except:
print("Good bye!")
Здесь самая суть, на практике периодический запуск удобнее оформить в виде класса.
И да, при изучении примеров по asyncio надо учитывать версию Python, со временем решения заметно менялись и это сбивает с толку.