ホームページ  >  記事  >  バックエンド開発  >  Pythonでループタイマーを実装する方法の紹介(コード付き)

Pythonでループタイマーを実装する方法の紹介(コード付き)

不言
不言転載
2019-03-14 11:13:0216961ブラウズ

この記事では、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 は時間間隔、function は呼び出し可能なオブジェクト、args と kwargs は function のパラメータとして使用されます。

注: この関数は 1 回のみ実行され、定期的に実行されるわけではありません。Timer は操作の実行時に新しいスレッドを作成します。

Python2 と Python3 の Timer にはわずかな違いがあります:

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

Python3 では、Timer は Thread のサブクラスですが、python2 では、_Timer は Thread のサブクラスであり、Timer は単なる_Timer クラスのファクトリ メソッド。

上記のコードは、hello, world を 1 回だけ出力して終了します。では、ループ内で間隔を置いて出力するにはどうすればよいでしょうか?

大まかなループ タイマー

1 つの方法は、関数にタイマーを登録し続けて、関数が次の間隔で実行され続けるようにすることです。

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

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

Every 10 秒 hello, world を出力します。

効果は得られましたが、ここで問題があるようです。タイマー自体に戻ると、これはスレッドですが、サイクル間隔が操作されるたびに、システムはスレッドを作成してリサイクルする必要があり、システムにとって非常にコストがかかります。時間間隔の間隔が非常に短い場合、システムは一度に多くのスレッドを作成し、これらのスレッドをすぐにリサイクルすることが難しく、システム メモリと CPU リソースが消費されます。
したがって、関数にタイマーを登録し続けることはお勧めできません。

その他の Python ループ タイマー

さらに Python メソッドの例を示します:

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

RepeatingTimer クラスに注目してください。このクラスは threading._Timer を継承しますが、親クラスの run メソッドを書き換えます。 Python2 はこのように書かれており、Python3 のRepeatingTimer は threading.Timer を継承する必要があります。

なぜ Thread の run メソッドをオーバーライドする必要があるのでしょうか?

_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 メソッドをオーバーライドし、実行されるコードを run に書き込むことができます。スレッドの作成後、ユーザーが start() メソッドを呼び出したときに run() メソッドが実行されます。

したがって、RepeatingTimer は、スレッドの実行本体を変更できる _Timer の run() メソッドをオーバーライドします。RepeatingTimer の start() メソッドを呼び出すと、書き換えた run() メソッドが実行されます。

RepeatingTimer クラスの while not self.finished.is_set() ステートメントを見てください。self.finished.is_set() は True になりタイマーが終了するまでループを終了しません。 completed は 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 の run メソッドは、while ループ本体を常に実行します。ループ本体では、ユーザーによって渡された関数オブジェクトが実行され、指定された時間待機します。ユーザーがタイマーを終了したい場合は、cancel メソッドを呼び出してフラグを True に設定するだけで、ループ本体の実行が続行されなくなります。これで、非常に優れたループ タイマーが完成しました。

以上がPythonでループタイマーを実装する方法の紹介(コード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。