이 기사에서는 Python에서 루프 타이머를 구현하는 방법을 소개합니다(코드 포함). 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.
루프에서 특정 작업을 수행하기 위해 Python으로 타이머를 작성하는 방법은 무엇입니까?
Timer 개체
from threading import Timer def hello(): print "hello, world" t = Timer(10.0, hello) t.start()
10초 후 출력:
hello, world
코드 t = Timer(10.0, hello)에 초점을 맞춥니다. Python은 지정된 시간 후에 특정 작업을 수행하는 Timer 개체를 제공합니다.
class threading.Timer(interval, function, args=[], kwargs={})
interval은 시간 간격이고, 함수는 호출 가능한 객체이며, args 및 kwargs는 함수의 매개변수로 사용됩니다.
참고: 함수는 한 번만 실행되며 정기적으로 실행되지 않으며 타이머는 작업을 실행할 때 새 스레드를 생성합니다.
Timer는 python2와 python3 사이에 약간 다릅니다.
# python2.7 def Timer(*args, **kwargs): return _Timer(*args, **kwargs) # python3.7 class Timer(Thread): pass
python3에서 Timer는 Python2의 Thread의 하위 클래스이고, _Timer는 Thread의 하위 클래스이고 Timer는 _Timer 클래스의 팩토리 메서드일 뿐입니다.
위 코드는 hello, world를 한 번만 인쇄한 다음 종료합니다. 그러면 루프에서 간격을 두고 인쇄하는 방법은 무엇입니까?
Crude 루프 타이머
한 가지 방법은 함수에 타이머를 계속 등록하여 다음 간격에도 함수가 계속 실행되도록 하는 것입니다.
from threading import Timer def hello(): print "hello, world" Timer(10.0, hello) .start() t = Timer(10.0, hello) t.start()
10초마다 hello, world를 출력합니다.
효과는 얻었지만 여기에는 문제가 있는 것 같습니다. 타이머 자체로 돌아가서, 이는 주기가 중단될 때마다 시스템이 스레드를 생성한 다음 이를 재활용해야 하며 이는 시스템에 매우 비용이 많이 듭니다. 시간 간격이 매우 짧은 경우 시스템은 한 번에 많은 스레드를 생성하게 되며 이러한 스레드는 빠르게 재활용하기 어려워 시스템 메모리와 CPU 리소스가 소모됩니다.
따라서 함수에 타이머를 계속 등록하는 것은 권장되지 않습니다.
더 많은 파이썬 루프 타이머
더 많은 파이썬 메서드는 다음과 같습니다.
from threading import _Timer def hello(): print "hello, world" class RepeatingTimer(_Timer): def run(self): while not self.finished.is_set(): self.function(*self.args, **self.kwargs) self.finished.wait(self.interval) t = RepeatingTimer(10.0, hello) t.start()
threading._Timer를 상속하지만 상위 클래스의 실행 메서드를 재정의하는 RepeatingTimer 클래스에 중점을 둡니다. 이것이 Python2의 Python3의 RepeatingTimer가 threading.Timer를 상속받는 방식입니다.
Thread의 실행 메서드를 재정의해야 하는 이유는 무엇인가요?
_Timer는 Thread 하위 클래스입니다. 먼저 Thread 클래스의 실행 사용법을 살펴보겠습니다.
from threading import Thread def hello(): print "hello, world" # 继承 Thread class MyThread(Thread): # 把要执行的代码写到run函数里面 线程在创建后会直接运行run函数 def run(self): hello() t = MyThread() t.start()
Thread 개체의 전체 정의:
class threading.Thread(group=None, target=None, name=None, args=(), kwargs={})
실행 메서드 코드:
class Thread(_Verbose): def run(self): try: if self.__target: self.__target(*self.__args, **self.__kwargs) finally: # Avoid a refcycle if the thread is running a function with # an argument that has a member that points to the thread. del self.__target, self.__args, self.__kwargs
표준 실행 메서드는 사용자가 생성자에 전달한 대상 메서드를 실행하는 데 사용됩니다. 서브클래스는 run 메서드를 재정의하고 실행할 코드를 run에 작성할 수 있습니다. 스레드가 생성된 후 사용자가 start() 메서드를 호출하면 run() 메서드가 실행됩니다.
그래서 RepeatingTimer는 스레드의 실행 본문을 변경할 수 있는 _Timer의 run() 메서드를 재정의합니다. RepeatingTimer의 start() 메서드를 호출하면 다시 작성된 run() 메서드가 실행됩니다.
RepeatingTimer 클래스의 while not self.finished.is_set() 문을 다시 살펴보세요. self.finished.is_set()는 True가 될 때까지 루프를 종료하지 않고 타이머가 종료됩니다. done 은 threading.Event 객체입니다. Event 객체는 set() 메소드에 의해 True로 설정되거나 Clear() 메소드에 의해 False로 설정될 수 있는 플래그를 관리합니다. wait([timeout])를 호출하면 스레드는 플래그가 True이거나 종료될 때까지 절전 모드로 유지됩니다. 시간 초과가 만료되었습니다.
우리는 타이머에 작업을 미리 취소할 수 있는 cancel() 메서드가 있다는 것을 알고 있습니다. 실제로 Event.clear() 메서드를 호출하여 wait 메서드가 미리 대기를 종료하도록 하고, 플래그가 true인 경우 타이머 동작을 수행하지 않을 것이라고 결정합니다. 특정 코드:
class _Timer(Thread): """Call a function after a specified number of seconds: t = Timer(30.0, f, args=[], kwargs={}) t.start() t.cancel() # stop the timer's action if it's still waiting """ def __init__(self, interval, function, args=[], kwargs={}): Thread.__init__(self) self.interval = interval self.function = function self.args = args self.kwargs = kwargs self.finished = Event() def cancel(self): """Stop the timer if it hasn't finished yet""" self.finished.set() def run(self): self.finished.wait(self.interval) if not self.finished.is_set(): self.function(*self.args, **self.kwargs) self.finished.set()
그래서 RepeatingTimer의 실행 메소드는 항상 while 루프 본문을 실행합니다. 루프 본문에서 사용자가 전달한 함수 개체가 실행되고 지정된 시간 동안 기다립니다. 사용자가 타이머를 종료하려면 취소 메서드를 호출하고 루프 본문이 계속 실행되지 않도록 플래그를 True로 설정하기만 하면 됩니다. 이것으로 꽤 좋은 루프 타이머가 완성되었습니다.
위 내용은 Python에서 루프 타이머를 구현하는 방법 소개(코드 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!