【问题标题】:Running exceptions within a function - Python在函数中运行异常 - Python
【发布时间】:2015-03-29 05:33:07
【问题描述】:

我已经学习 Python 大约 3 周了,所以我的工作显然非常简单。我已经编写了几个程序来为某些计算返回值,并且我已经成功地在这些程序的函数中使用了异常。我目前正在编写的程序只是为了让我更多地练习编写函数、while 循环和异常。到目前为止,这是我所得到的:

def factorial(n):
    while n > 0:
        return n * factorial(n-1)
    return 1

    print factorial(n)

def user():
    n = int(raw_input("What number would you like to use?"))
    try:
        factorial(int(n))
    except ValueError:
        print "You must choose a number. Please try again."
        return user()


if __name__ == '__main__':
    user()

我不明白为什么user() 函数中的异常似乎没有运行。当我运行这段代码时,我得到的只是raw_input "What number would you like to use?"factorial() 函数不会运行,如果有ValueError,我设置的printreturn 语句也不会运行。谁能帮我弄清楚为什么会(或者说不会)发生这种情况?

【问题讨论】:

  • 您在raw_input 周围有int,它不在try 块内。将int(raw_input("What number would you like to use?")) 放在try 之后,将factorial 放在except 块之后
  • 另外 - 看看this post,为什么使用递归对于重复输入请求是个坏主意......

标签: python function exception


【解决方案1】:

有趣的是,所有的代码都在运行!它只是没有显示任何内容,因为没有调用 print 语句!让我们分解用户函数,看看它做了什么。

代码在做什么

n = int(raw_input("What number would you like to use?"))

将用户键入的字符串转换为整数并将其存储到变量中(或者,如果您想完全正确,则为namen

try:
    factorial(int(n))

尝试(再次)将n 转换为整数并将所述整数发送到factorial 函数。注意这里的n 已经是一个整数了!所以这总是会成功的。只需调用该函数,仅此而已。

except ValueError:
    print "You must choose a number. Please try again."
    return user()

如果引发了ValueError,则打印一条错误消息,然后返回user 的值。

无论转换是否成功,我们都不会打印任何内容。我们只运行一个函数然后退出。我们运行什么函数?

def factorial(n):
    while n > 0:
        return n * factorial(n-1)
    return 1

    print factorial(n)

请注意,在此函数中,代码表示要在 返回一个值之后打印一个值。一旦函数返回,在 return 语句运行之后什么都不会运行。 print 语句将不会被执行!所以这个函数正确地计算阶乘(递归),并返回它。没有别的!

这就是为什么你的程序似乎什么都不做的原因。这个函数被调用、计算并返回答案。返回的答案会被忽略!

这是什么意思?

您的代码中有三个关键行定义了它为什么要这样做。

  1. 您将来自用户的输入转换为整数并将其存储在n
    • 如果用户输入的不是整数,这将引发ValueError
    • 请注意,这仍然会发生!如果你运行代码,输入b,然后回车,就会抛出异常(ValueError)。
  2. 您将n 转换为整数并将其传递给factorial
    • 虽然这是在try 块中(应该如此),但n 已经是一个整数。 这就是你的异常代码永远不会运行的原因。
  3. 您唯一的打印语句(在从用户获得有效输入后)位于factorial 函数内,位于 return 语句之后。它永远不会被执行。 这就是为什么什么都不打印的原因。
    • 我不建议在递归函数中打印结果。可以这样做,但通常最好返回结果并打印返回值,在递归函数之外。 (也许在用户函数中,而不是调用factorial(n) 打印它返回的内容会更好!)

我希望这有助于澄清代码到底发生了什么,我希望我能够回答您的问题!快乐编码! :D

【讨论】:

  • @wwii 有趣。我承认我不知道“名字”的花絮,并将记住它以备将来使用。但是,第一个链接说,我引用:Although we commonly refer to "variables" even in Python (because it's common terminology), ...。尽管我同意应该使用“正确”的术语,但只要语言的用户理解术语的含义,我觉得你怎么称呼它并不重要。正如莎士比亚所说:“任何其他名字的玫瑰都会闻起来一样甜美。” (至少我相信那是他。)不过,我还是把它添加到我的帖子中。知道这一点很重要。
  • 在 Python 中说你将一个值 放入 一个变量是误导性的,并且在操作/改变值时有时会引起一些混乱。我只是想详细说明您的陈述-store it into the variable
  • @wwii 很有趣,因为您发布的第二个链接(事实和神话)与您写的第一个声明直接矛盾。来自 ned 的文章:Myth: Python has no variables. Some people like to say, "Python has no variables, it has names." This slogan is misleading.
  • @wim。看来我已经把自己带到了一个滑坡上。第一个有点简单 - 但那句话肯定卡在我的脑海里。希望我以后会更加小心我如何表达事物。谢谢。
【解决方案2】:

这是我的 cmets 扩展为答案。

首先,不要在factorial 函数内打印。打印从该函数返回的值:

def factorial(n):
    while n > 0:
        return n * factorial(n-1)
    return 1

>>> factorial(4)
24

接下来,将你认为会导致异常的东西包装在块的try 部分。在这种情况下,使用未知用户输入调用int 可能会导致异常;将其包装在尝试中-不再。最后,不要对用户输入使用递归。改用 while 循环:

def user():
    n=None
    while not n:
        user_int=raw_input("What number would you like to use? ")
        try:
            n=int(user_int)
        except ValueError:
            print "You must choose a number. Please try again."

    print factorial(n)   

if __name__ == '__main__':
    user() 

【讨论】:

    【解决方案3】:

    首先你必须printfactorial(int(n))才能看到输出, 并删除您输入的int 转换,

    这是我修改后的代码:

    def factorial(n):
      2     while n > 0:
      3        return n *factorial(n-1)
      4     return 1
      5     print factorial(n)
      6 
      7 
      8 
      9 
     10 def user():
     11     n = raw_input("What number would you like to use?")
     12 
     13     try:
     14 
     15         print factorial(int(n))
     16     except ValueError:
     17         print "You must choose a number. Please try again."
     18         return user()
     19 
     20 if __name__ == '__main__':
     21     user()
    

    希望这会有所帮助,

    【讨论】:

      猜你喜欢
      • 2011-11-13
      • 1970-01-01
      • 1970-01-01
      • 2018-03-24
      • 1970-01-01
      • 1970-01-01
      • 2010-12-18
      • 2022-11-16
      • 1970-01-01
      相关资源
      最近更新 更多