【问题标题】:Python RecursionError: maximum recursion depth exceededPython RecursionError:超出最大递归深度
【发布时间】:2020-07-13 18:53:21
【问题描述】:

我编写了一个 Python 程序,可以全天随太阳移动我的太阳能电池板。它工作正常,但大约每周两次我得到 RecursionError: maximum recursion depth exceeded

我对 python 还很陌生,我查过 Recursion Errors,它说当一个函数调用自身太多次时,我看不出这个程序中发生了什么。

    from datetime import date
    from datetime import datetime, timezone, timedelta
    import astral
    from astral import Astral
    import time
    import pytz


    # import RPi.GPIO as GPIO

    # Global Variables
    ast = Astral()
    city_Name = 'Cleveland'
    local_City = ast[city_Name]
    # sun_Position = local_City.sun(local=True)
    reset_Solar = True

    # Retrieves and returns current time
    def get_Current_Time():
        eastern = pytz.timezone('America/New_York')
        curr_Time = datetime.now(eastern)
        return curr_Time

    def main_Function():
        global local_City
        sun_Position = local_City.sun(local=True)
        current_Time = get_Current_Time()
        solar_Sunrise = sun_Position.get('sunrise')
        solar_Noon = sun_Position.get('noon')
        solar_Sunset = sun_Position.get('sunset')
        calc_Sunrise_Noon = solar_Noon - solar_Sunrise

        total_Seconds = calc_Sunrise_Noon.seconds
        calc_Hours, remainder = divmod(total_Seconds, 3600)
        calc_Minutes, calc_Seconds = divmod(remainder, 60)

        time_To_Adjust = total_Seconds / 24

        print (current_Time)
        print (solar_Sunrise)

        if current_Time >= solar_Sunrise and current_Time < solar_Sunset:
            solar_Adjust_Active(time_To_Adjust)
        elif reset_Solar == True:
            reset_Solar_Panel()
        else:
            solar_Adjust_Deactive()

    def solar_Adjust_Active(time_To_Adjust):

        while time_To_Adjust > 0:
            current_Time = get_Current_Time()
            time_To_Adjust = time_To_Adjust - 1
            time.sleep(1)
            print (current_Time)
            print (time_To_Adjust)
        daylight_Adjustment()

    def solar_Adjust_Deactive():
        global local_City
        curr_Time = get_Current_Time()
        calc_Tomorrow = curr_Time.date() + timedelta(days=1)
        sun_Position_Tomorrow = local_City.sun(local=True, date = calc_Tomorrow)
        solar_Sunrise_Tomorrow = sun_Position_Tomorrow.get('sunrise')

        time_Till_Sunrise = solar_Sunrise_Tomorrow - curr_Time

        sunrise_Total_Seconds = time_Till_Sunrise.seconds
        calc_Sunrise_Hours, remainder = divmod(sunrise_Total_Seconds, 3600)
        calc_Sunrise_Minutes, calc_Sunrise_Seconds = divmod(remainder, 60)

        while sunrise_Total_Seconds > 0:
            sunrise_Total_Seconds = sunrise_Total_Seconds - 1
            time.sleep(1)
            # print ('Seconds till Sunrise', sunrise_Total_Seconds)
        print (solar_Sunrise_Tomorrow)
        main_Function()

    def daylight_Adjustment():
        global reset_Solar
        # Adustment to Solar Panel
        #GPIO.setmode(GPIO.BCM)

        # init pin numbers
        #pin_Open = [6]

        # set mode default state is 'low'
        #GPIO.setup(pin_Open, GPIO.OUT) 

        # Activate Open Relay to High (High turns Relay on)
        #GPIO.output(pin_Open, GPIO.HIGH)     # Activate Open relay

        # Start Timer for duration actuator will be activated
        timer = 0
        while timer < 1:
            time.sleep(1)
            timer = timer + 1

        print ('Panal adjusted')
        # set Open relay back to low (Turns Relay off)
        #GPIO.output(pin_Open, GPIO.LOW)

        # Reset GPIO settings
        #GPIO.cleanup()

        reset_Solar = True
        main_Function()

     def reset_Solar_Panel():
        global reset_Solar
        print ('Setting panel back to original position')
        # Adustment to Solar Panel
        # GPIO.setmode(GPIO.BCM)

        # init pin numbers
        # pin_Open = [XX]

        # set mode default state is 'low'
        # GPIO.setup(pin_Open, GPIO.OUT) 

        # Activate Open Relay to High (High turns Relay on)
        # GPIO.output(pin_Open, GPIO.HIGH)     # Activate Open relay

        # Start Timer for duration actuator will be activated
        timer = 0
        while timer <= 48:
            time.sleep(1)
            timer = timer + 1

        # set Open relay back to low (Turns Relay off)
        # GPIO.output(pin_Open, GPIO.LOW)

        # Reset GPIO settings
        # GPIO.cleanup()

        reset_Solar = False
        main_Function()

    main_Function()

【问题讨论】:

  • 好吧,您的main_Function() 在某些条件下调用reset_Solar_Panel(),而后者又调用main_Function(),并且其他一些方法也可以这样做。这解释了超出递归限制的错误。

标签: python raspberry-pi


【解决方案1】:

您的代码中有(至少一个)循环:

def main_Function(): 
->  solar_Adjust_Active(time_To_Adjust)  
->  daylight_Adjustment() 
->  main_Function() -> .... # lets run that for a couple of days ...

通常你有一个主循环(例如while True:)并从函数调用/返回到你的主循环而不递归:

伪代码:

def resetToStart():
    move panels to sunrise position
    return

def movePanel():
    get_currnt_optimal_position_for_datetime
    move_to_that_position
    return

resetToStart()  # start at a well known position
while True:
    if NightTime:  # sun is down
        resetToStart() 
        sleep till daytime
    elif DayTime:  # sun is up
        movePanel() 
        sleep some till adjustment needed

【讨论】:

  • 好吧,看看你写的,这很有意义。我已经调整了程序,我会让它运行大约一个星期,看看我是否有任何错误。感谢您的帮助。
猜你喜欢
  • 2017-03-24
  • 2020-10-08
  • 2018-09-24
  • 2019-04-18
  • 2019-01-18
  • 1970-01-01
  • 2017-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多