Heim  >  Artikel  >  Backend-Entwicklung  >  Einführung in die Methode zur Implementierung eines Schleifentimers in Python (mit Code)

Einführung in die Methode zur Implementierung eines Schleifentimers in Python (mit Code)

不言
不言nach vorne
2019-03-14 11:13:0216965Durchsuche

Was dieser Artikel Ihnen bietet, ist eine Einführung in die Methode zur Implementierung eines Schleifentimers in Python (mit Code). Ich hoffe, dass er einen gewissen Referenzwert hat wird Ihnen nützlich sein.

Wie schreibe ich einen Timer in Python, um eine bestimmte Operation in einer Schleife auszuführen?

Timer-Objekt

from threading import Timer
def hello(): 
    print "hello, world" 
   
t = Timer(10.0, hello) 
t.start()

Ausgabe nach 10 Sekunden:

hello, world

Konzentrieren Sie sich auf den Code t = Timer(10.0, hallo). Python stellt ein Timer-Objekt bereit, das einen ausführt Operation nach der angegebenen Zeit; ihre vollständige Form:

class threading.Timer(interval, function, args=[], kwargs={})

interval ist das Zeitintervall, die Funktion ist ein aufrufbares Objekt und args und kwargs werden als Parameter der Funktion verwendet.

Hinweis: Die Funktion wird nur einmal und nicht regelmäßig ausgeführt. Der Timer erstellt beim Ausführen des Vorgangs einen neuen Thread.

Timer ist in Python2 und Python3 etwas anders:

# python2.7
def Timer(*args, **kwargs):
    return _Timer(*args, **kwargs)
# python3.7
class Timer(Thread):
    pass

In Python3 ist Timer eine Unterklasse von Thread; in Python2 ist _Timer eine Unterklasse von Thread und Timer ist nur eine Factory-Methode von die _Timer-Klasse.

Der obige Code gibt „Hallo, Welt“ nur einmal aus und wird dann beendet. Wie druckt man also in Abständen in einer Schleife?

Grobschleifen-Timer

Eine Möglichkeit besteht darin, weiterhin einen Timer in der Funktion zu registrieren, damit die Funktion im nächsten Intervall weiterhin ausgeführt werden kann;

from threading import Timer
def hello(): 
    print "hello, world" 
    Timer(10.0, hello) .start()

t = Timer(10.0, hello) 
t.start()

Alle 10 Sekunden Gibt ein Hallo Welt aus.

Der Effekt wird erzielt, aber hier scheint es ein Problem zu geben. Zurück zum Timer selbst: Jedes Mal, wenn der Zyklus unterbrochen wird, muss das System einen Thread erstellen und ihn dann recyceln, was für das System sehr teuer ist. Wenn das Zeitintervall sehr kurz ist, erstellt das System viele Threads gleichzeitig, und es ist schwierig, diese Threads schnell wiederzuverwenden, was dazu führt, dass Systemspeicher und CPU-Ressourcen verbraucht werden.
Es wird daher nicht empfohlen, weiterhin einen Timer in der Funktion zu registrieren.

Mehr Python-Schleifen-Timer

Hier ist eine pythonischere Methode:

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()

Konzentrieren Sie sich auf die RepeatingTimer-Klasse, die threading._Timer erbt, aber die Ausführungsmethode der übergeordneten Klasse neu schreibt. So sollte Python2 in Python3 den Threading.Timer erben.

Warum sollten wir die Ausführungsmethode von Thread überschreiben?

_Timer ist eine Thread-Unterklasse. Schauen wir uns zunächst die Ausführungsverwendung der Thread-Klasse an.

from threading import Thread
def hello():
     print "hello, world"
# 继承 Thread
class MyThread(Thread):
    # 把要执行的代码写到run函数里面 线程在创建后会直接运行run函数
    def run(self):
        hello()
t = MyThread()
t.start()

Vollständige Definition des Thread-Objekts:

class threading.Thread(group=None, target=None, name=None, args=(), kwargs={})

Der Code der Ausführungsmethode:

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

Die Standardausführungsmethode wird verwendet, um die vom Benutzer an die übergebene Zielmethode auszuführen Konstrukteur. Unterklassen können die run-Methode überschreiben und den auszuführenden Code in run schreiben. Nachdem der Thread erstellt wurde, wird die run()-Methode ausgeführt, wenn der Benutzer die start()-Methode aufruft.

RepeatingTimer überschreibt also die run()-Methode von _Timer, was den Ausführungskörper des Threads ändern kann. Wenn wir die start()-Methode von RepeatingTimer aufrufen, wird unsere überschriebene run()-Methode ausgeführt.

Sehen Sie sich die while not self.finished.is_set()-Anweisung in der RepeatingTimer-Klasse an. self.finished.is_set() verlässt die Schleife erst, wenn True und der Timer abgelaufen ist. Fertig ist ein threading.Event-Objekt. Ein Event-Objekt verwaltet ein Flag, das mit der Methode set() auf „True“ oder mit der Methode „clear()“ auf „False“ gesetzt werden kann. Beim Aufruf von wait([timeout]) bleibt der Thread im Ruhezustand, bis das Flag „True“ oder „True“ ist Timeout läuft ab.

Wir wissen, dass der Timer über eine cancel()-Methode verfügt, die den Vorgang im Voraus abbrechen kann. Es ruft tatsächlich die Methode Event.clear () auf, damit die Wartemethode das Warten im Voraus beendet, und bestimmt, dass die Timer-Operation nicht ausgeführt wird, wenn das Flag wahr ist. Spezifischer Code:

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()

Die Ausführungsmethode von RepeatingTimer führt also immer den While-Schleifenkörper aus. Im Schleifenkörper wird das vom Benutzer übergebene Funktionsobjekt ausgeführt und wartet auf die angegebene Zeit. Wenn der Benutzer den Timer verlassen möchte, muss er nur die Abbruchmethode aufrufen und das Flag auf True setzen, damit der Schleifenkörper nicht weiter ausgeführt wird. Damit ist ein ziemlich guter Loop-Timer fertig.

Das obige ist der detaillierte Inhalt vonEinführung in die Methode zur Implementierung eines Schleifentimers in Python (mit Code). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen