超时后Python执行函数

时间:2018-07-13 17:37:28

标签: python

我想在While true循环中超时后启动一个函数,但是代码不执行任何操作并跳出循环,我不知道为什么:/

这是我的代码

import requests
from threading import Timer

def timeout(flag):
            print("New Request")
            statuscode = requests.get("http://adslkfhdsjf.de").status_code
            if statuscode == 200 and flag == 0:
                print("Service available")
            #Testzwecke
            print("Flag: ", flag)
            flag = 0
            #Poste result to Backend
        elif statuscode == 200 and flag == 1: 
            print("Service is available now")
            print("Flag: ", flag)
            flag = 0
            #Email an User
            #Post Request
        elif statuscode != 200 and flag == 0:
            print("Service is not available")
            #Testzwecke
            print("Flag: ", flag)
            flag = 1
            #Email to User
            #Post Request
        else: 
            print("Service is not available")
            #Testzwecke
            print("Flag: ", flag)
            #Post Request
        Timer(10, timeout, flag)

timeout(0)

我希望例如每10秒执行一次超时。因此,每隔10秒就会从功能timeout()中执行一个条件。

但是到目前为止它还不能正常工作,控制台输出什么也没有:/

1 个答案:

答案 0 :(得分:3)

您的第一个问题就是您没有打电话给main()。通常,我只是添加一条评论告诉您,然后以错别字的形式关闭该问题,但是您直到第一次解决更大的问题之前都不想解决该问题。

您的代码试图一遍又一遍地创建并调用新的timeout函数。 timeout函数要做的第一件事是创建一个新的Timer对象。这是一个新线程。

因此,您将以Python允许的最快速度生成新线程,这意味着在很短的时间内,您将拥有比操作系统能够处理的线程更多的线程。如果幸运的话,那将意味着您将获得一个异常并且程序退出。如果您不走运,这将意味着您的系统会因为内核开始将线程堆栈交换到磁盘上而使爬网速度变慢,即使您设法杀死该程序,它仍可能需要几分钟才能恢复。

实际上,这里没有理由while循环。每个Timer都会调度下一个Timer,因此它将永远运行。这样一来,一次只有2个线程处于活动状态。

但是首先甚至没有理由使用Timer。在两次请求之间等待10秒时,您不想执行任何操作,那么为什么不只是sleep

import time
import requests

def main():
    flag = 0
    while True:
        print("New Request")
        statuscode = requests.get("http://google.de").status_code
        if statuscode == 200 and flag == 0:
            print("Service available")
            # etc.
        time.sleep(10)

main()

您的代码还有另一个问题:您在flag中定义了一个名为timeout的局部变量,但是在您进行flag == 0检查之前,您尝试使用它曾经分配给它。那会产生一个UnboundLocalError。您恰好在flag中也有一个名为main的局部变量这一事实并没有什么不同。要解决此问题,您必须执行以下一项操作:

  • flag作为参数传递给Timer,以作为参数传递给每个timeout调用。 (可能是最好的。)
  • nonlocal flag添加timeout声明,这样它就成为您定义的所有timeout函数共享的闭包单元。 (不错,但不是最惯用的解决方案。)
  • 在两个函数中添加一个global flag声明,因此它成为Universe中每个人共享的全局变量。 (可能很简单,但最好不要养成习惯。)

但是,一旦我们摆脱了线程,我们也摆脱了函数,因此只有一个本地flag,因此问题不会首先出现。