Python:在函数本身中调用函数是一种好的做法吗?

Python:在函数本身中调用函数是一种好的做法吗?,python,function,if-statement,Python,Function,If Statement,只是一个关于良好实践的初学者问题 以这段代码为例。我需要一个特定的用户输入,如果他们输入了一些疯狂的东西,我显然希望再次在函数中运行代码 def get_difficulty(): chosen_difficulty = str(raw_input("*** Choose difficulty: Easy, Medium or Hard: ").lower()) if chosen_difficulty == "hard": return 10 elif

只是一个关于良好实践的初学者问题

以这段代码为例。我需要一个特定的用户输入,如果他们输入了一些疯狂的东西,我显然希望再次在函数中运行代码

def get_difficulty():
    chosen_difficulty = str(raw_input("***  Choose difficulty: Easy, Medium or Hard: ").lower())
    if chosen_difficulty == "hard":
        return 10
    elif chosen_difficulty == "medium":
        return 15
    elif chosen_difficulty == "easy":
        return 20       
    else:
        print "***  Did you enter 'Easy', 'Medium' or 'Hard'?"
        print "***  Sorry that was passive aggressive. You obviously didn't..."
        return get_difficulty() 
让函数像这样处理else情况可以吗?这似乎不雅;如果用户输入了错误的内容五次,那么函数将嵌套五次,最终正确的答案必须通过每个函数的返回进行级联


它工作正常,但有更好的方法吗?

在您的情况下,循环是处理重复输入的正确方法:

def get_difficulty():
    while True:
        chosen_difficulty = raw_input("***  Choose difficulty: Easy, Medium or Hard: ").lower()
        try:
            return {"hard": 10, "medium": 15, "easy": 20}[chosen_difficulty]
        except KeyError:
            print "***  Did you enter 'Easy', 'Medium' or 'Hard'?"
            print "***  Sorry that was passive aggressive. You obviously didn't..."

在您的情况下,循环是处理重复输入的正确方法:

def get_difficulty():
    while True:
        chosen_difficulty = raw_input("***  Choose difficulty: Easy, Medium or Hard: ").lower()
        try:
            return {"hard": 10, "medium": 15, "easy": 20}[chosen_difficulty]
        except KeyError:
            print "***  Did you enter 'Easy', 'Medium' or 'Hard'?"
            print "***  Sorry that was passive aggressive. You obviously didn't..."

你所发现的被称为“递归”,它基本上没有什么错。这是一个强有力的概念,常常导致问题的优雅表述。斐波那契数是一个经常出现的问题,很容易通过递归解决:我们想要生成数字序列1,1,2,3,5,8,13。。因此
n+1
条目是(n-1)+(n)。这将导致以下算法:

def fibonacci(n):
    """Generate the n-th fibonacci number"""
    if n == 0 or n == 1:
        return(1)
    else:
        return(fibonacci(n-2) + fibonacci(n-1))
每个递归函数都可以转化为迭代函数。对于第n个fibonacci序列,存在一个闭合形式,您可以查找它。正如你所看到的,有两个“无理数”,可以用2的平方根的和/除来表示。因此,有时问题是“本质上递归的”,递归解决方案可能很短,而迭代解决方案可能“看起来很难看”/“更长”

所以递归通常是一件好事,但在python中它并不总是一个好的解决方案。正如您已经指出的,如果用户五次插入错误的输入,函数堆栈将有五次函数调用。Python有一个最大重现深度,如果用户连续输入错误的输入,可能会使程序崩溃。在用户输入的情况下,这不是一个真正的问题,但在其他情况下,您可以更容易地运行到最大递归深度

尾部递归(未在python中实现)是一种允许任意递归深度的方法。Haskell和lisp使用了这个概念,您可以在或上阅读更多


正如Daniel所指出的,python中处理输入验证的规范方法是while循环。

您所发现的被称为“递归”,它基本上没有什么错。这是一个强有力的概念,常常导致问题的优雅表述。斐波那契数是一个经常出现的问题,很容易通过递归解决:我们想要生成数字序列1,1,2,3,5,8,13。。因此
n+1
条目是(n-1)+(n)。这将导致以下算法:

def fibonacci(n):
    """Generate the n-th fibonacci number"""
    if n == 0 or n == 1:
        return(1)
    else:
        return(fibonacci(n-2) + fibonacci(n-1))
每个递归函数都可以转化为迭代函数。对于第n个fibonacci序列,存在一个闭合形式,您可以查找它。正如你所看到的,有两个“无理数”,可以用2的平方根的和/除来表示。因此,有时问题是“本质上递归的”,递归解决方案可能很短,而迭代解决方案可能“看起来很难看”/“更长”

所以递归通常是一件好事,但在python中它并不总是一个好的解决方案。正如您已经指出的,如果用户五次插入错误的输入,函数堆栈将有五次函数调用。Python有一个最大重现深度,如果用户连续输入错误的输入,可能会使程序崩溃。在用户输入的情况下,这不是一个真正的问题,但在其他情况下,您可以更容易地运行到最大递归深度

尾部递归(未在python中实现)是一种允许任意递归深度的方法。Haskell和lisp使用了这个概念,您可以在或上阅读更多


Daniel指出,python中处理输入验证的规范方法是while循环。

您所发现的(从自身调用函数)是编程中的一个基本概念,称为。除了在这种情况下,它被用来模拟循环,而这不是尾部递归语言,所以@我承认,我只是读了标题并浏览了代码。我同意对于他的具体情况,循环是一种更好的方法。此外,您可能应该添加一行
choosted\u demobility=choosted\u demobility.lower()
您给用户的选项是“简单、中等等”,但是
if…elif
中的选项会阻止用户使用小写。它是。lower()ed,但它只是在屏幕外:)您所发现的(从自身调用函数)是编程中的一个基本概念,称为。除了在这种情况下,它被用来模拟循环,而这不是尾部递归语言,所以@我承认,我只是读了标题并浏览了代码。我同意对于他的具体情况,循环是一种更好的方法。此外,您可能应该添加一行
choosted\u demobility=choosted\u demobility.lower()
您给用户的选项是“简单、中等等”,但是
if…elif
中的选项会阻止用户使用小写。它是。lower()ed,但它只是在屏幕外:)您的dict键和被动攻击性错误文本之间的大小写不匹配。但它是
.lower()
ed。@tripleee-谢谢。lower()刚从我的屏幕上消失。您的dict键和被动攻击性错误文本之间的大小写不匹配。但它正在
。lower()
ed.@tripleee-谢谢。下面的()刚从我的屏幕上消失。