【问题标题】:How do i make a infinite loop with def function?如何使用 def 函数进行无限循环?
【发布时间】:2023-04-02 22:37:01
【问题描述】:

我编写了一个程序,它每 5 秒检查一次日志文件中的特定词。 当它找到那个词时,它会发出一些噪音并覆盖日志文件。 问题是在我得到某个点之后:

RuntimeError:调用 Python 对象时超出了最大递归深度。

有没有更好的方法来制作这个循环?

import time
import subprocess
global playalarm

def alarm():
    if "No answer" in open("/var/log/hostmonitor.log").read():
        print "Alarm!"
        playalarm=subprocess.Popen(['omxplayer','/root/Alarm/alarm.mp3'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,close_fds=True)
        log = open("/var/log/hostmonitor.log","w")
        log.write("Checked")
        log.close()
        time.sleep(5)
        playalarm.stdin.write('q')
        alarm()
    else:
        print"Checked"
        time.sleep(5)
        alarm()

alarm()

【问题讨论】:

  • 你所认为的函数的“本地范围”存储在一个数据结构中,当进入一个方法时它被压入堆栈,当方法退出时它被弹出。由于您无限调用警报函数,而没有完成任何调用,因此您超过了最大堆栈深度(这是有限的),并看到此错误。简单的解决方法是使用循环而不是递归。

标签: python function infinite-loop


【解决方案1】:

你可以像这样使用无限循环

def alarm():
    while True:
        if "No answer" in open("/var/log/hostmonitor.log").read():
            print "Alarm!"
            playalarm=subprocess.Popen(['omxplayer','/root/Alarm/alarm.mp3'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,close_fds=True)
            log = open("/var/log/hostmonitor.log","w")
            log.write("Checked")
            log.close()
            time.sleep(5)
            playalarm.stdin.write('q')
        else:
            print"Checked"
            time.sleep(5)

这个错误

RuntimeError: 超出最大递归深度

因为alarm() 函数的无限递归调用。每个递归调用都需要一定量的堆栈内存。栈空间是有限的,递归调用一定次数后栈就会溢出。为了防止这种情况,Python 限制了最大递归深度。
在您的情况下,您根本不需要递归。

【讨论】:

    【解决方案2】:

    每次alarm() 调用自己时,您都会使用更多的堆栈空间,最终因为供应不是无限的而耗尽。

    你需要的是一个循环:

    def alarm():
        while True:
            if "No answer" in open("/var/log/hostmonitor.log").read():
                print "Alarm!"
                playalarm=subprocess.Popen(['omxplayer','/root/Alarm/alarm.mp3'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,close_fds=True)
                log = open("/var/log/hostmonitor.log","w")
                log.write("Checked")
                log.close()
                time.sleep(5)
                playalarm.stdin.write('q')
            else:
                print"Checked"
                time.sleep(5)
    

    但您应该记住,结束该程序的唯一方法是终止它(例如,使用 CTRL-Ckill)。可能值得重新考虑它,以便您可以以更清洁的方式将其关闭。

    【讨论】:

    • 是的,但是程序应该运行并且永不停止。谢谢你的回答。
    【解决方案3】:

    使用while True

    代码:

    def func():
        while true:
            #Remaining function
    

    更多关于while loop look in to this SO question

    while True 将永远运行,您必须使用 Ctrl+c 或在循环内使用 break 来停止它

    【讨论】:

    • while true 的解释非常有帮助,谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 2021-07-16
    • 1970-01-01
    • 2018-11-18
    相关资源
    最近更新 更多