Python: 每 x 分钟交替调用函数

11 投票
4 回答
1287 浏览
提问于 2025-04-16 18:11

假设我有下面这四个函数:

def foo():
    subprocess.Popen('start /B someprogramA.exe', shell=True)

def bar():
    subprocess.Popen('start /B someprogramB.exe', shell=True)

def foo_kill():
    subprocess.Popen('taskkill /IM someprogramA.exe')

def bar_kill():
    subprocess.Popen('taskkill /IM someprogramB.exe')

我该如何让这两个函数 foo 和 bar 每隔30分钟交替运行一次呢?

意思是:第一个30分钟运行 foo,第二个30分钟运行 bar,第三个30分钟再运行 foo,以此类推。每次新的运行应该“结束”上一个线程或函数。

我有一个倒计时的线程,但不太确定怎么“交替”这些函数。

class Timer(threading.Thread):
    def __init__(self, minutes):
        self.runTime = minutes
        threading.Thread.__init__(self)


class CountDownTimer(Timer):
    def run(self):
        counter = self.runTime
        for sec in range(self.runTime):
            #do something           
            time.sleep(60) #editted from 1800 to 60 - sleeps for a minute
            counter -= 1

timeout=30
c=CountDownTimer(timeout)
c.start()

编辑:这是我根据 Nicholas Knight 的建议找到的解决方案……

import threading
import subprocess
import time

timeout=2 #alternate delay gap in minutes

def foo():
    subprocess.Popen('start /B notepad.exe', shell=True)

def bar():
    subprocess.Popen('start /B calc.exe', shell=True)

def foo_kill():
    subprocess.Popen('taskkill /IM notepad.exe')

def bar_kill():
    subprocess.Popen('taskkill /IM calc.exe')


class Alternator(threading.Thread):
    def __init__(self, timeout):
        self.delay_mins = timeout 
        self.functions = [(foo, foo_kill), (bar, bar_kill)]
        threading.Thread.__init__(self)

    def run(self):
        while True:
            for f, kf in self.functions:
                f()
                time.sleep(self.delay_mins*60)
                kf()

a=Alternator(timeout)
a.start()

运行得很好。

4 个回答

2

用一个变量来记录你上次运行的是哪个函数。当计时器触发时,运行另一个函数,并更新这个变量。

10

记住,在Python中,函数是第一类对象。这意味着你可以把它们存储在变量和容器里!一种实现的方法是:

funcs = [(foo, foo_kill), (bar, bar_kill)]

def run(self):
    counter = self.runTime
    for sec in range(self.runTime):
        runner, killer = funcs[counter % 2]    # the index alternates between 0 and 1
        runner()    # do something
        time.sleep(1800)
        killer()    # kill something
        counter -= 1
6

你把这个搞得太复杂了。

while True:
    foo()
    time.sleep(1800)
    foo_kill()
    bar()
    time.sleep(1800)
    bar_kill()

或者如果你想以后更方便地添加更多功能:

functions = [(foo, foo_kill), (bar, bar_kill), ] # Just append more as needed
while True:
    for f, kf in functions:
        f()
        time.sleep(1800)
        kf()

撰写回答