python使用称为异常的特殊类对象来管理程序执行期间发生的错误,每当发生让python不知所措的错误时,他都会创建一个异常的对象。
如果你编写了处理该异常的代码,程序将继续进行,如果未对异常进行处理,程序将停止并显示traceback,其中包含有关异常的报告。
异常是使用 try-except 代码块处理的。try-except 代码块让 Python 执行指定的操作,同时告诉python发生异常时怎么办,使用try-except代码块时,即便出现异常,程序也将继续运行,显示你编写的友好的错误消息,而不是令用户迷惑的 traceback。
处理ZeroDivisionErro:
举例:
我们早已在数学中学过,0不能在分母的位置,但还是让python执行如下程序:
print(5/0)
输出结果产生了traceback:
Traceback (most recent call last):
File "C:/Users/Lenovo/PycharmProjects/pythonProject4/main.py", line 14, in <module>
print(5/0)
ZeroDivisionError: division by zero
在上述 traceback中,指出的错误 ZeroDivisionError 是个异常对象。Python 无法按你的要求做时,就会创建这种对象。在这种情况下,**Python 将停止运行程序,并指出引发了哪种异常,**而我们可根据这些信息对程序进行修改。下面来告诉 Python,发生这种错误时怎么办。这样,如果再次发生此类错误,我们就有备无患了。
当你认为可能发生错误时,可编写一个代码块try-except代码块来处理可能引发的异常,你让python尝试运行一些代码,并告诉它如果这些代码引发了指定的异常该怎么办。
处理ZeroDivisionErro异常的try-except代码块类似于下面这样:
try:
print(5/0)
except ZeroDivisionError:
print("you can't divide by zero")
将导致错误的代码行print(5/0)放在一个try代码块中,如果try代码块中的代码运行起来没有问题,python将跳过execpt代码块,如果try代码块中的代码导致了错误,python将查找与之匹配的except代码块并运行其中的代码。
you can't divide by zero
如果except代码块后面还有其他代码块,程序将接着运行,因为已经告诉python如何处理这种错误。
发生错误时,如果程序还有工作尚未完成,妥善处理错误就显得尤其重要,这种情况经常会出现在要求用户提供输入的程序中,如果程序能够妥善的处理无效输入,就能再提示用户提供有效输入,而不至于崩溃。
举例:
该程序是实现求两个数的商
print("Give me two numbers,and I'll divide them.")
print("enter 'q' to quit")
while True:
fist_number=input("\nfist number:")
if fist_number=='q':
break
second_number=input("\nsecond number:")
if second_number=='q':
break
answer=int(fist_number)/int(second_number)
print(answer)
由于对被除数为0的这种情况未作任何处理,所以当被除数为0时,会出现异常
Give me two numbers,and I'll divide them.
enter 'q' to quit
fist number:19
second number:0
Traceback (most recent call last):
File "C:/Users/Lenovo/PycharmProjects/pythonProject4/main.py", line 24, in <module>
answer=int(fist_number)/int(second_number)
ZeroDivisionError: division by zero
程序崩溃可不好,但让用户看到 traseback 也不是个好主意。不懂技术的用户会被搞糊涂。怀有恶意的用户还会通过 traceback 获悉你不想他知道的信息。例如,他将知道你的程序文件的名称,还将看到部分不能正确运行的代码。有时候,训练有素的攻击者可根据这些信息判断出可对你的代码发起什么样的攻击。
那么应该怎么妥善解决这个问题呢?
答案是:使用try-except代码块,那么具体怎么操作呢?
通过将可能引发错误的代码块放入try-except代码块中,可提高程序抵御错误的能力。
举例:
while True:
fist_number=input("\nfist number:")
if fist_number=='q':
break
second_number=input("\nsecond number:")
if second_number=='q':
break
try:
answer=int(fist_number)/int(second_number)#可能引发程序崩溃的代码
except ZeroDivisionError:
print("you can't divide by 0!")#try语句后程序未成功运行,友情提示错误的消息内容
else:
print(answer)#try语句后程序成功运行的代码
Give me two numbers,and I'll divide them.
enter 'q' to quit
fist number:12
second number:0#当被除数是0
you can't divide by 0!#会输出良好的友情提醒而不是程序崩溃
python尝试执行try代码块中的代码,只有可能引发错误的代码才需要放在try语句中,有时候,有一些仅在try代码块成功执行时才需要运行的代码,这些代码应放在else代码块中,except代码块告诉python,如果尝试运行try代码块时引发了指定的异常该怎么办。
使用文件时,一种常见的问题就是找不到文件,查找的文件可能在其他地方,文件名可能不正确,或者这个文件根本不存在,对于所有这些情况,都可使用try-except代码块以直观的方式进行处理。
举例:
下面我们通过读取系统不存在的文件:
with open("789.txt",encoding='utf-8') as f:
f.read()
python无法读取不存在的文件,因此它将引发异常:
Traceback (most recent call last):
File "C:/Users/Lenovo/PycharmProjects/pythonProject4/main.py", line 30, in <module>
with open("789.txt",encoding='utf-8') as f:
FileNotFoundError: [Errno 2] No such file or directory: '789.txt'
上述中的Traceback的最后一行报告了FileNotFoundError异常,这是python找不到要打开的文件时创建的异常,在本例中,是由open函数导致的,因此,要处理这个错误,必须将try语句放在包含open()的代码行之前:
优化之后的代码:
try:
filename='789.txt'
with open("filename",encoding='utf-8') as f:
f.read()
except FileNotFoundError:
print(f"sorry,the file{filename}does not exist")
如下图所示,当文件不存在时,python此时并没有引发异常,而是输出一条提示的信息。
sorry,the file789.txtdoes not exist
如果文件不存在,这个程序就什么也做不了,错误处理代码的意义不大。
分析文本:
你可以分析包含整本书的文本文件。
举例:
filename="123.txt"
try:
with open(filename,encoding="utf-8") as f:
contents=f.read()#运行成功,执行else代码块后面的语句
except FileNotFoundError:
print(f"sorry,the file{filename} does not exist")
else:
words=contents.split()#以空格作为标记符号,将字符串分隔开
num_words=len(words)#计算字符串的长度
print(f"the file {filename} has about {num_words} words")
the file 123.txt has about 98 words
123.txt内容如下:
Currently,there is a widespread concern over (the issue that)__作文题目 .
It is really an important concern to every one of us. As a result,we must spare no efforts to take some measures to
solve this problem.As we know that there are many steps which can be taken to undo this problem. First of all,__途径一
_In addition, another way contributing to successfully solving the problem is 途径二Above all, to solve the problem of
___作文题目,we should find a number of various ways. But as far as I am concerned, I would prefer to solve the problem
in this way,that is to say, 方法
使用多个文件:
下面同时多分析几本书:
在此之前我们先将这个程序的代码移到一个名为count_words的函数中,这样,对多本书的分析就会更加方便。
def count_words(filename):#计算一个文件里面大致包含多少词
try:
with open(filename,encoding="utf-8") as f:
contents=f.read()
except FileNotFoundError:
print(f"sorry,the file{filename} does not exist")
else:
words=contents.split()
num_words=len(words)
print(f"the file {filename} has about {num_words} words")
fliename=["123.txt","456.py"]#将多个文本存储在一个列表中
for filename in fliename:#使用for循环对其进行遍历
count_words(filename)#依次调用函数对不同文本的词进行统计
the file 123.txt has about 14 words
the file 456.py has about 42 words
如果其中的某个文件不存在呢?
使用try-except代码块的效果:
def count_words(filename):#计算一个文件里面大致包含多少词
try:
with open(filename,encoding="utf-8") as f:
contents=f.read()
except FileNotFoundError:
print(f"sorry,the file{filename} does not exist")
else:
words=contents.split()
num_words=len(words)
print(f"the file {filename} has about {num_words} words")
fliename=["123.txt","789.py","456.py"]#将多个文本存储在一个列表中
for filename in fliename:#使用for循环对其进行遍历
count_words(filename)#依次调用函数对不同文本的词进行统计
the file 123.txt has about 14 words
sorry,the file789.py does not exist
the file 456.py has about 42 words
不使用try-except代码块的效果:
def count_words(filename):#计算一个文件里面大致包含多少词
# try:
with open(filename,encoding="utf-8") as f:
contents=f.read()
words=contents.split()
num_words=len(words)
print(f"the file {filename} has about {num_words} words")
fliename=["123.txt","789.py","456.py"]
for filename in fliename:
count_words(filename)
the file 123.txt has about 14 words
Traceback (most recent call last):
File "C:/Users/Lenovo/PycharmProjects/pythonProject4/main.py", line 41, in <module>
count_words(filename)
File "C:/Users/Lenovo/PycharmProjects/pythonProject4/main.py", line 32, in count_words
with open(filename,encoding="utf-8") as f:
FileNotFoundError: [Errno 2] No such file or directory: '789.py'
通过对比上述两个的执行效果,我们发现使用try_except代码块,在某文件不存在的情况下,编译器不仅不会发生异常,而且不存在文件后面的文件依然会被编译器进行分析,而不使用try-except代码块,在某文件不存在的情况下,traceback不仅被完整显示,而且后面的文本编译器不会进行分析。
这样对比,是不是觉得使用try——except代码块更友好一些?
静默失败:
在上面的示例中,我们告诉用户有一个文件找不到,但并非每次产生异常都要告诉用户,有时候你希望程序在发生异常时保持静默,就像什么都没有发生一样继续运行,要让程序静默失败,可像通常编写try代码块那样,但在except代码块中明确告诉python什么都不要做,python有一个pass语句,可让python在代码块中什么都不要做。
举例:
def count_words(filename):#计算一个文件里面大致包含多少词
try:
with open(filename,encoding="utf-8") as f:
contents=f.read()
except FileNotFoundError:
pass#当出现异常时,python将不会告诉用户任何东西
else:
words=contents.split()
num_words=len(words)
print(f"the file {filename} has about {num_words} words")
fliename=["123.txt","789.py","456.py"]#将多个文本存储在一个列表中
for filename in fliename:#使用for循环对其进行遍历
count_words(filename)#依次调用函数对不同文本的词进行统计
相比于前面的程序,这个程序唯一不同的地方就是在except代码块后面使用的是pass语句,现在,当
出现FileNotFoundError异常时,将执行except代码块中的代码,但什么都不会输出,这种错误发生时,不会出现traceback,也没有任何输出语句,用户将看到存在的文件输出的内容,但不会看到有文件没有被找到的内容。
the file 123.txt has about 14 words
the file 456.py has about 42 words
pass语句还充当了占位符,提醒你在程序的某个地方什么都没做,并且以后需要在这里做些什么。
如果用户知道要分析哪些文件,他们可能希望在有文件却没有分析时出现一条消息来告知原因。
如果用户只想看到结果,并不知道要分析那些文件,可能就无须在有些文件不存在时告知他们。向用户显示他不想看到的信息可能会降低程序的可用性。Python 的错误处理结构让你能够细致地控制与用户分享错误信息,要分享多少信息由你决定。
编写得很好且经过详尽测试的代码不容易出现内部错误,如语法或逻辑错误,但只要程序依
赖于外部因素,如用户输人、存在指定的文件、有网络链接,就有可能出现异常。凭借经验可判
该在程序的什么地方包含异常处理块。以及出现错误时,该向用户提供多少相关的信息。
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信
我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A