Python 如何对非正数进行例外处理
Python how to make an exception for non positive numbers
如何在此处引发异常以捕获非正输入?现在如果我输入一个负数就不会打印任何东西
"""
Generate fibonacci sequence to the nth digit
"""
def fib(n):
try:
if n <= 0:
raise Exception
prev = 0
curr = 1
for terms in range(0, int(n)):
nxt = prev + curr
print str(curr),
prev = curr
curr = nxt
except ValueError or Exception:
new = raw_input("Invalid input. Please enter a positive integer: ")
fib(new)
n = raw_input("Enter number of terms: ")
fib(n)
except ValueError or Exception
正确的语法是 except (ValueError, Exception)
,但请注意,由于所有异常都继承自 Exception
,因此这可能会出现错误。
您最好不要引发并尝试捕获一般异常。
相反,提高已经捕获的 ValueError
:
def fib(n):
try:
if n <= 0:
raise ValueError
.
.
.
except ValueError:
.
.
.
要捕获多种异常类型,请将它们放在一个元组中。 ValueError or Exception
是一个计算结果为 ValueError 的布尔表达式。
此外,您永远不应该引发异常,也不应该捕获它。定义您自己的自定义异常 class。
class NonNegativeNumber(Error):
pass
...
except (ValueError, NonNegativeNumber):
但是,请注意,ValueError 似乎是在这里引发的一个完全有效的异常;您可能根本不需要更具体的 class。
我认为这里的核心问题是您的 fib
函数有两个完全独立的职责:
- 处理用户输入和验证;和
- 计算斐波那契数列。
从名字来看,我会说它应该只做#2!
相反,将您的程序结构化为:
def positive_integer():
"""Loops until the user enters a positive integer."""
...
def fib(n):
"""Prints first n Fibonacci numbers."""
if n < 0:
raise ValueError
prev = 0
curr = 1
for terms in range(n): # note simplification here
nxt = prev + curr
print str(curr),
prev = curr
curr = nxt
fib(positive_integer())
现在您有两个函数,每个函数都有明确的单一职责。这使得每一个都不那么复杂; range
调用现在更简单了,例如,因为它可以假设 n
已经是一个整数(如果不是,用户会得到一个明智的 TypeError
来告诉他们出了什么问题)。
写positive_input
见Asking the user for input until they give a valid response;为此,循环比递归更好。
作为进一步的重构,其实可以把这三行删掉
nxt = prev + curr
prev = curr
curr = nxt
只有一个:
prev, curr = curr, curr + prev
另请注意,一般而言,您应使 try
块尽可能短,而 except
子句应尽可能具体。这使它们在阅读代码 ("I think this one thing could go wrong, and in that case we can do this about it") 时更有用,并且意味着不会悄悄地忽略合法问题。特别是,你几乎不应该直接处理 Exception
(在 raise
或 except
中),它的范围太广而无法有效处理。
正如 Jon 所说,将输入收集与核心 Fibonacci 计算分开是一种更好的设计策略。此外,使用简单循环通常比使用递归调用(在其自身内部调用函数)更好,除非你真的需要递归(例如,在处理递归数据结构时,如目录树)。
这是您的代码的修改版本。我做了一些其他的小改动。在 Python 中,我们不需要像 nxt
这样的临时变量来进行核心斐波那契计算。相反,我们使用元组赋值,这样我们就可以一步更新 curr
并将旧的 curr
保存到 prev
。
def input_positive_integer(prompt=''):
""" Get a positive integer from the user """
while True:
try:
n = int(raw_input(prompt))
if n <= 0:
raise ValueError
break
except ValueError:
print "Invalid input.",
prompt = "Please enter a positive integer: "
return n
def fib(n):
""" Print n terms of the Fibonacci sequence """
prev, curr = 0, 1
for terms in range(n):
print curr,
prev, curr = curr, prev + curr
n = input_positive_integer("Enter number of terms: ")
fib(n)
测试
Enter number of terms: -4
Invalid input. Please enter a positive integer: q
Invalid input. Please enter a positive integer: 2.5
Invalid input. Please enter a positive integer: 5
1 1 2 3 5
如何在此处引发异常以捕获非正输入?现在如果我输入一个负数就不会打印任何东西
"""
Generate fibonacci sequence to the nth digit
"""
def fib(n):
try:
if n <= 0:
raise Exception
prev = 0
curr = 1
for terms in range(0, int(n)):
nxt = prev + curr
print str(curr),
prev = curr
curr = nxt
except ValueError or Exception:
new = raw_input("Invalid input. Please enter a positive integer: ")
fib(new)
n = raw_input("Enter number of terms: ")
fib(n)
except ValueError or Exception
正确的语法是 except (ValueError, Exception)
,但请注意,由于所有异常都继承自 Exception
,因此这可能会出现错误。
您最好不要引发并尝试捕获一般异常。
相反,提高已经捕获的 ValueError
:
def fib(n):
try:
if n <= 0:
raise ValueError
.
.
.
except ValueError:
.
.
.
要捕获多种异常类型,请将它们放在一个元组中。 ValueError or Exception
是一个计算结果为 ValueError 的布尔表达式。
此外,您永远不应该引发异常,也不应该捕获它。定义您自己的自定义异常 class。
class NonNegativeNumber(Error):
pass
...
except (ValueError, NonNegativeNumber):
但是,请注意,ValueError 似乎是在这里引发的一个完全有效的异常;您可能根本不需要更具体的 class。
我认为这里的核心问题是您的 fib
函数有两个完全独立的职责:
- 处理用户输入和验证;和
- 计算斐波那契数列。
从名字来看,我会说它应该只做#2!
相反,将您的程序结构化为:
def positive_integer():
"""Loops until the user enters a positive integer."""
...
def fib(n):
"""Prints first n Fibonacci numbers."""
if n < 0:
raise ValueError
prev = 0
curr = 1
for terms in range(n): # note simplification here
nxt = prev + curr
print str(curr),
prev = curr
curr = nxt
fib(positive_integer())
现在您有两个函数,每个函数都有明确的单一职责。这使得每一个都不那么复杂; range
调用现在更简单了,例如,因为它可以假设 n
已经是一个整数(如果不是,用户会得到一个明智的 TypeError
来告诉他们出了什么问题)。
写positive_input
见Asking the user for input until they give a valid response;为此,循环比递归更好。
作为进一步的重构,其实可以把这三行删掉
nxt = prev + curr
prev = curr
curr = nxt
只有一个:
prev, curr = curr, curr + prev
另请注意,一般而言,您应使 try
块尽可能短,而 except
子句应尽可能具体。这使它们在阅读代码 ("I think this one thing could go wrong, and in that case we can do this about it") 时更有用,并且意味着不会悄悄地忽略合法问题。特别是,你几乎不应该直接处理 Exception
(在 raise
或 except
中),它的范围太广而无法有效处理。
正如 Jon 所说,将输入收集与核心 Fibonacci 计算分开是一种更好的设计策略。此外,使用简单循环通常比使用递归调用(在其自身内部调用函数)更好,除非你真的需要递归(例如,在处理递归数据结构时,如目录树)。
这是您的代码的修改版本。我做了一些其他的小改动。在 Python 中,我们不需要像 nxt
这样的临时变量来进行核心斐波那契计算。相反,我们使用元组赋值,这样我们就可以一步更新 curr
并将旧的 curr
保存到 prev
。
def input_positive_integer(prompt=''):
""" Get a positive integer from the user """
while True:
try:
n = int(raw_input(prompt))
if n <= 0:
raise ValueError
break
except ValueError:
print "Invalid input.",
prompt = "Please enter a positive integer: "
return n
def fib(n):
""" Print n terms of the Fibonacci sequence """
prev, curr = 0, 1
for terms in range(n):
print curr,
prev, curr = curr, prev + curr
n = input_positive_integer("Enter number of terms: ")
fib(n)
测试
Enter number of terms: -4
Invalid input. Please enter a positive integer: q
Invalid input. Please enter a positive integer: 2.5
Invalid input. Please enter a positive integer: 5
1 1 2 3 5