简体   繁体   English

尽管接受输入,Python递归函数仍返回0

[英]Python recursive function returning 0 despite taking input

This is more of a why, rather than a "how do I fix this" question.这更像是一个为什么,而不是一个“我该如何解决这个问题”的问题。

I'm attempting to take an input of time, whether seconds, minutes, hours, or days, and then return the number of seconds that measurement is equal to with this code:我正在尝试输入时间,无论是秒、分钟、小时还是天,然后使用以下代码返回测量值等于的秒数:

#!/usr/bin/env python3

valid_measurements = {
    "s": "1",
    "m": "60",
    "h": "3600",
    "d": "86400"
}


def print_err(err_type):
    if err_type == "time_format":
        print('\tTime should be entered as s/m/h/d')
        print('\t\ts = seconds')
        print('\t\tm = minutes')
        print('\t\th = hours')
        print('\t\td = days')
        print('\tFormat: "30s" or "20m" or "1h"')
        print('\tFormat: "30 s" or "20 m" or "1 h" ')


def input_time(time_type):
    time_value = 0
    multiplier = 0

    time = input("Enter " + time_type + ": ")

    if time[-1] in valid_measurements:
        measurement = time[-1]
        time_value = int(time[0:-1].rstrip())
        multiplier = int(valid_measurements[measurement])
    else:
        print_err("time_format")
        # For some reason this returns 0 for either value
        input_time(time_type)

    return time_value * multiplier


def main():
    work_time = input_time("Work Time")
    break_time = input_time("Break Time")

    print("Real work time: " + str(work_time))
    print("Real break time: " + str(break_time))

main()

However, I get this output when I attempt to break the code:但是,当我尝试破坏代码时,我得到了这个输出:

Enter Work Time: 20
    Time should be entered as s/m/h/d
        s = seconds
        m = minutes
        h = hours
        d = days
    Format: "30s" or "20m" or "1h"
    Format: "30 s" or "20 m" or "1 h" 
Enter Work Time: 20m
Enter Break Time: 5m
Real work time: 0
Real break time: 300

Process finished with exit code 0

Why does real work time return 0, despite me using the correct format for the input on the second round of the function when it calls itself?尽管我在函数的第二轮调用自身时使用了正确的输入格式,但为什么real work time返回 0? Additionally, is there anything I can do to clean up this code and make it more efficient or python-esque?此外,我可以做些什么来清理此代码并使其更高效或更像 Python 那样?

The Problem问题

else:
    print_err("time_format")
    # For some reason this returns 0 for either value
    input_time(time_type)

You recursively call input_time , but never store its output.您递归调用input_time ,但从不存储其输出。 What ends up happening is it will keep recursively calling the function, and once you have a valid input, the return will never be stored and when you reach the final call in the recursive stack, return time_value * multiplier will be 0 because time value and multiplier are still 0.最终发生的是它将继续递归调用该函数,一旦你有一个有效的输入,返回将永远不会被存储,当你到达递归堆栈中的最终调用时, return time_value * multiplier将为 0,因为时间值和乘数仍为0。

Simple Fix简单修复

One way to simply fix this is to return the output of the recursive call:简单解决此问题的一种方法是返回递归调用的输出:

else:
    print_err("time_format")
    return input_time(time_type)

A Better Fix更好的修复

It's not a good idea to use recursion for invalid user input since you can theoretically have a stack overflow error.对无效的用户输入使用递归不是一个好主意,因为理论上您可能会遇到堆栈溢出错误。 Instead use a while loop:而是使用 while 循环:

def input_time(time_type):
    time_value = 0
    multiplier = 0

    time = input("Enter " + time_type + ": ")

    while time[-1] not in valid_measurements:
        print_err("time_format")
        time = input("Enter " + time_type + ": ")

    measurement = time[-1]
    time_value = int(time[0:-1].rstrip())
    multiplier = int(valid_measurements[measurement])

    return time_value * multiplier

Making it Pythonic使其成为 Pythonic

Finally, one thing you can change to make you're code more "pythonic" is to replace your last line of code (the main() call) with this:最后,您可以更改使您的代码更“pythonic”的一件事是用以下代码替换您的最后一行代码(main() 调用):

if __name__ == "__main__":
    main()

When you import a python module it will run the entire file, so for example if you had another file that wanted to use the functions you created in this file, when you import this file, it would've inadvertently run main().当你导入一个 python 模块时,它会运行整个文件,例如,如果你有另一个文件想要使用你在这个文件中创建的函数,当你导入这个文件时,它会无意中运行 main()。 To prevent this, you would use the above, which only runs main() if the file was called directly (aka name == " main ").为了防止这种情况,您可以使用上面的方法,如果直接调用文件(又名名称==“ main ”),它只会运行main() ) 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM