First of all, your function doesn't return anything and so you can remove -> bool
since it only creates confusion. You can either use -> None
or use nothing at all. Still related to type annotations, I find it kinda hard to read your code with annotations everywhere. This is subjective and it's just my personal preference but I usually tend to use type annotations only when dealing with function / class definitions and their arguments.
For example, milliseconds: int = int(round(time.time() * 1000))
it's obviously going to be an integer since we can see the cast to int()
.
More, round()
already returns an int
in your case so that can be removed as well. The done
variable can also be omitted and added directly to the condition itself:
def set_timer(interval: int, function: Callable) -> None:
global last_milliseconds
milliseconds = round(time.time() * 1000)
if milliseconds - last_milliseconds >= interval:
function()
last_milliseconds = milliseconds
You can also remove the parentheses from your condition since -
has a higher precedence than >=
.
Strictly speaking about the implementation, if you're not tied to using a function and want to get rid of the usage of global
, I'd use a class:
from time import time
from typing import Callable
class Timer:
def __init__(self):
self.last_milliseconds = 0
def set(self, interval: int, function: Callable) -> None:
milliseconds = round(time() * 1000)
if milliseconds - self.last_milliseconds >= interval:
function()
self.last_milliseconds = milliseconds
Which can be used like this:
def main():
timer = Timer()
while True:
timer.set(1000, lambda: print("set_timer called."))
main()
Or, even better, you can have a static class if your workflow allows it:
class StaticTimer:
last_milliseconds = 0
@classmethod
def set(cls, interval: int, function: Callable) -> None:
milliseconds = round(time() * 1000)
if milliseconds - cls.last_milliseconds >= interval:
function()
cls.last_milliseconds = milliseconds
Which you'd call like this:
def main():
while True:
StaticTimer.set(1000, lambda: print("set_timer called."))
main()
The difference between the two classes is that you can't have multiple of the latter because of the class attribute and @classmethod
. So even if you made multiple instance of the class, they'd all share that value.