错误和异常(1)

错误

语法错误(syntax errors)

>>> for i in range(10)
  File "<stdin>", line 1
    for i in range(10)
                     ^
SyntaxError: invalid syntax

上面那句话因为缺少冒号:,导致解释器无法解释,于是报错。这个报错行为是由python的语法分析器完成的,并且检测到了错误所在文件和行号(File "<stdin>", line 1),还以向上箭头^标识错误位置(后面缺少:),最后显示错误类型。

逻辑错误

逻辑错误可能会由于不完整或者不合法的输入导致,也可能是无法生成、计算等,或者是其它逻辑问题。

当python检测到一个错误时,解释器就无法继续执行下去,于是抛出异常。

异常

>>> 1/0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

当python抛出异常的时候,首先有“跟踪记录(Traceback)”,还可以给它取一个更优雅的名字“回溯”。后面显示异常的详细信息。异常所在位置(文件、行、在某个模块)。

NameError


python中变量需要初始化,即要赋值。虽然不需要像某些语言那样声明,但是要赋值先。因为变量相当于一个标签,要把它贴到对象上才有意义。

ZeroDivisionError

>>> 1/0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

貌似这样简单的错误时不会出现的,但在实际情境中,可能没有这么容易识别,所以,依然要小心为妙。

SyntaxError

>>> for i in range(10)
  File "<stdin>", line 1
    for i in range(10)
                     ^
SyntaxError: invalid syntax

这种错误发生在python代码编译的时候,当编译到这一句时,解释器不能讲代码转化为python字节码,就报错。只有改正才能继续。所以,它是在程序运行之前就会出现的(如果有错)。现在有不少编辑器都有语法校验功能,在你写代码的时候就能显示出语法的正误,这多少会对编程者有帮助。

IndexError

>>> a = [1,2,3]
>>> a[4]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

>>> d = {"python":"itdiffer.com"}
>>> d["java"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: ‘java‘

这两个都属于“鸡蛋里面挑骨头”类型,一定得报错了。不过在编程实践中,特别是循环的时候,常常由于循环条件设置不合理出现这种类型的错误。

IOError

>>> f = open("foo")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: ‘foo‘

如果你确认有文件,就一定要把路径写正确,因为你并没有告诉python对你的computer进行全身搜索,所以,python会按照你指定位置去找,找不到就异常。

AttributeError

>>> class A(object): pass
...
>>> a = A()
>>> a.foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: ‘A‘ object has no attribute ‘foo‘

属性不存在。这种错误前面多次见到。

其实,python内建的异常也不仅仅上面几个,上面只是列出常见的异常中的几个。比如还有:

>>> range("aaa")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: range() integer end argument expected, got str.

总之,如果读者在调试程序的时候遇到了异常,不要慌张,这是好事情,是python在帮助你修改错误。只要认真阅读异常信息,再用dir()help()或者官方网站文档、google等来协助,一定能解决问题。

处理异常

在一段程序中,为了能够让程序健壮,必须要处理异常。

处理异常的方式之一,使用try...except...

只看try和except部分,如果没有异常发生,except子句在try语句执行之后被忽略;如果try子句中有异常可,该部分的其它语句被忽略,直接跳到except部分,执行其后面指定的异常类型及其子句。

except后面也可以没有任何异常类型,即无异常参数。如果这样,不论try部分发生什么异常,都会执行except。

处理多个异常

处理多个异常,并不是因为同时报出多个异常。程序在运行中,只要遇到一个异常就会有反应,所以,每次捕获到的异常一定是一个。所谓处理多个异常的意思是可以容许捕获不同的异常,有不同的except子句处理。

#!/usr/bin/env python
# coding=utf-8

while 1:
    print "this is a division program."
    c = raw_input("input ‘c‘ continue, otherwise logout:")
    if c == ‘c‘:
        a = raw_input("first number:")
        b = raw_input("second number:")
        try:
            print float(a)/float(b)
            print "*************************"
        except ZeroDivisionError:
            print "The second number can‘t be zero!"
            print "*************************"
        except ValueError:
            print "please input number."
            print "************************"
    else:
        break

将上节的一个程序进行修改,增加了一个except子句,目的是如果用户输入的不是数字时,捕获并处理这个异常。测试如下:

$ python 21701.py
this is a division program.
input ‘c‘ continue, otherwise logout:c
first number:3
second number:"hello"        #输入了一个不是数字的东西
please input number.         #对照上面的程序,捕获并处理了这个异常
************************
this is a division program.
input ‘c‘ continue, otherwise logout:c
first number:4
second number:0
The second number can‘t be zero!
*************************
this is a division program.
input ‘c‘ continue, otherwise logout:4
$

如果有多个except,在try里面如果有一个异常,就转到相应的except子句,其它的忽略。如果except没有相应的异常,该异常也会抛出,不过这是程序就要中止了,因为异常“浮出”程序顶部。

除了用多个except之外,还可以在一个except后面放多个异常参数,比如上面的程序,可以将except部分修改为:

except (ZeroDivisionError, ValueError):
    print "please input rightly."
    print "********************"

运行的结果就是:

$ python 21701.py
this is a division program.
input ‘c‘ continue, otherwise logout:c
first number:2
second number:0           #捕获异常
please input rightly.
********************
this is a division program.
input ‘c‘ continue, otherwise logout:c
first number:3
second number:a           #异常
please input rightly.
********************
this is a division program.
input ‘c‘ continue, otherwise logout:d
$

需要注意的是,except后面如果是多个参数,一定要用圆括号包裹起来。否则,后果自负。

突然有一种想法,在对异常的处理中,前面都是自己写一个提示语,发现自己写的不如内置的异常错误提示更好。希望把它打印出来。但是程序还能不能中断。python提供了一种方式,将上面代码修改如下:

while 1:
    print "this is a division program."
    c = raw_input("input ‘c‘ continue, otherwise logout:")
    if c == ‘c‘:
        a = raw_input("first number:")
        b = raw_input("second number:")
        try:
            print float(a)/float(b)
            print "*************************"
        except (ZeroDivisionError, ValueError), e:
            print e
            print "********************"
    else:
        break

运行一下,看看提示信息。

$ python 21702.py
this is a division program.
input ‘c‘ continue, otherwise logout:c
first number:2
second number:a                         #异常
could not convert string to float: a
********************
this is a division program.
input ‘c‘ continue, otherwise logout:c
first number:2
second number:0                         #异常
float division by zero
********************
this is a division program.
input ‘c‘ continue, otherwise logout:d
$

在python3.x中,常常这样写:except (ZeroDivisionError, ValueError) as e:

以上程序中,之处理了两个异常,还可能有更多的异常呢?如果要处理,怎么办?可以这样:execpt:或者except Exception, e,后面什么参数也不写就好了。

else子句

有了try...except...,在一般情况下是够用的,但总有不一般的时候出现,所以,就增加了一个else子句。其实,人类的自然语言何尝不是如此呢?总要根据需要添加不少东西。

>>> try:
...     print "I am try"
... except:
...     print "I am except"
... else:
...     print "I am else"
...
I am try
I am else

这段演示,能够帮助读者理解else的执行特点。如果执行了try,则except被忽略,但是else被执行。

>>> try:
...     print 1/0
... except:
...     print "I am except"
... else:
...     print "I am else"
...
I am except

这时候else就不被执行了。

#!/usr/bin/env python
# coding=utf-8
while 1:
    try:
        x = raw_input("the first number:")
        y = raw_input("the second number:")

        r = float(x)/float(y)
        print r
    except Exception, e:
        print e
        print "try again."
    else:
        break

先看运行结果:

$ python 21703.py
the first number:2
the second number:0        #异常,执行except
float division by zero
try again.                 #循环
the first number:2
the second number:a        #异常
could not convert string to float: a
try again.
the first number:4
the second number:2        #正常,执行try
2.0                        #然后else:break,退出程序
$

需要对程序中的except简单说明,这次没有像前面那样写,而是except Exception, e,意思是不管什么异常,这里都会捕获,并且传给变量e,然后用print e把异常信息打印出来。

finally

finally子句,一听这个名字,就感觉它是做善后工作的。的确如此,如果有了finally,不管前面执行的是try,还是except,它都要执行。因此一种说法是用finally用来在可能的异常后进行清理。比如:

>>> x = 10

>>> try:
...     x = 1/0
... except Exception, e:
...     print e
... finally:
...     print "del x"
...     del x
...
integer division or modulo by zero
del x

看一看x是否被删除?

>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name ‘x‘ is not defined

assert

assert,翻译过来是“断言”之意。assert是一句等价于布尔真的判定,发生异常就意味着表达式为假。

assert的应用情景就有点像汉语的意思一样,当程序运行到某个节点的时候,就断定某个变量的值必然是什么,或者对象必然拥有某个属性等,简单说就是断定什么东西必然是什么,如果不是,就抛出错误。

!/usr/bin/env python
# coding=utf-8

class Account(object):
    def __init__(self, number):
        self.number = number
        self.balance = 0

    def deposit(self, amount):
        assert amount > 0
        self.balance += balance

    def withdraw(self, amount):
        assert amount > 0
        if amount <= self.balance:
            self.balance -= amount
        else:
            print "balance is not enough."

上面的程序中,deposit()和withdraw()方法的参数amount值必须是大于零的,这里就用断言,如果不满足条件就会报错。比如这样来运行:

if __name__ == "__main__":
    a = Account(1000)
    a.deposit(-10)

出现的结果是:

$ python 21801.py
Traceback (most recent call last):
  File "21801.py", line 22, in <module>
    a.deposit(-10)
  File "21801.py", line 10, in deposit
    assert amount > 0
AssertionError

这就是断言assert的引用。什么是使用断言的最佳时机?有文章做了总结:

如果没有特别的目的,断言应该用于如下情况:

  • 防御性的编程
  • 运行时对程序逻辑的检测
  • 合约性检查(比如前置条件,后置条件)
  • 程序中的常量
  • 检查文档
 
时间: 2024-09-29 05:14:27

错误和异常(1)的相关文章

PHP 错误与异常的日志记录

提到 Nginx + PHP 服务的错误日志,我们通常能想到的有 Nginx 的 access 日志.error 日志以及 PHP 的 error 日志.虽然看起来是个很简单的问题,但里面其实又牵扯到应用配置以及日志记录位置的问题,如果是在 ubuntu 等系统下使用 apt-get 的方式来安装,其自有一套较为合理的的配置文件可用.再者运行的应用程序中的配置也会影响到日志记录的方式及内容. 错误与异常的区别 关于错误与异常,我们可以用一个简单的例子来理解: <?php try { 1 / 0;

初识Python(8)__Python错误和异常

错误和异常 ################################################################################## 参考:http://blog.csdn.net/fcoolx/article/details/4202872 http://blog.163.com/[email protected]/blog/static/279729562008719384580/ https://docs.python.org/2/library

有关错误与异常的总结

错误和异常的区别(Error vs Exception) 1)  error都是继承自父类java.lang.Error,而exception都继承自java.lang.Exception. 2)  再看看JDK中对于java.lang.Error和java.lang.Exception的解释.    java.lang.Error: An Error is a subclass of Throwable that indicates serious problems that a reason

Python学习笔记七-错误和异常

程序员总是和各种错误打交道,学习如何识别并正确的处理程序错误是很有必要的. 7.1错误和异常 1.错误 从软件方面来看,错误分为语法错误和逻辑错误两种.这两种错误都将导致程序无法正常进行下去,当Python检测到一个错误时就出现了异常. 2.异常 当编译器检测到错误并且意识到错误条件.解释器会引发一个异常(程序员也可以自己引发一个异常,后面会说到). 以下是7种Python中常见的错误. 1.NameError,尝试访问一个未申明的例子. 2.ZeroDivisionError,零除错误. 3.

10 错误和异常 - 《Python 核心编程》

?? 什么是异常? ?? Python 中的异常 ?? 探测和处理异常 ?? 上下文管理 ?? 引发异常 ?? 断言 ?? 标准异常 ?? 创建异常 ?? 相关模块 10.1 什么是异常人们需要一个"柔和"的处理错误的方法, 而不是终止程序. 错误 从软件方面来说, 错误是语法或是逻辑上的. 当 Python 检测到一个错误时, 解释器就会指出当前流已经无法继续执行下去. 这时候就出现了异常. 语法错误 语法错误指示软件的结构上有错误, 导致不能被解释器解释或编译器无法编译. 逻辑错误

C#高级编程----错误和异常的总结

错误和异常的总结 因为总结吗,,可能概念啥的比较多,大家要学着适应. 首先是C#中的异常用老处理系统级和用户级的错误状态,是一种结构化,统一的类型安全的处理机制. 因为鄙人开始想走C++的道路,所以搞过一段时间的C++,感觉C#还是和C++的异常处理有点区别的. 1.在C#中,所有的异常必须由Exception派生的类类型的实例来表示.在C++中,可以使用任何类型的任何值表示异常. 2.在C#中,利用finally块可编写正常执行和异常情况下都将执行的终止代码.在C++中,很难在不重复代码的情况

PHP 错误与异常 笔记与总结(10)错误处理器测试

关联文件:myErrorHandler.php (上一篇) 先测试通知级别的错误的自定义处理: testErrorHandler.php <?php require_once 'myErrorHandler.php'; error_reporting(-1); set_error_handler(array('myErrorHandler', 'deal')); //通知级别错误 echo $notice; 运行,在 D:\practise\php\From\notice 生成 noticeLo

未能加载文件或程序集“Antlr3.Runtime”或它的某一个依赖项。参数错误。 (异常来自 HRESULT:0x80070057 (E_INVALIDARG))

未能加载文件或程序集“Antlr3.Runtime”或它的某一个依赖项.参数错误. (异常来自 HRESULT:0x80070057 (E_INVALIDARG)) 别的办法都没用,直接删除出问题的dll,再重新引用就好了. 位置:C:\Program Files (x86)\Microsoft Web Tools\Packages\WebGrease.1.1.0\lib

Python错误和异常概念

本文和大家分享的主要是python中常见的错误与异常及其相关处理方式,一起来看看吧,希望对大家学习python有所帮助. 1. 错误和异常的处理方式 1.常见的错误 1. a:NameError 2. if True:SyntaxError 3. f = oepn('1.txt'):IOError 4. 10/0:ZeroDivisionError 5. a = int('d'):ValueError 6. 程序运行中断:KeyboardInterrupt 2.Python-使用try_exce

Python错误和异常 学习笔记

错误和异常概念 错误: 1.语法错误:代码不符合解释器或者编译器语法 2.逻辑错误:不完整或者不合法输入或者计算出现问题 异常:执行过程中出现万体导致程序无法执行 1.程序遇到逻辑或者算法问题 2.运行过程中计算机错误(内存不够或者IO错误) 错误和异常区别 错误: 代码运行前的语法或者逻辑错误, 语法错误在执行前修改,逻辑错误无法修改 异常分为两个步骤: 1.异常产生,检查到错误且解释器认为是异常,抛出异常: 2.异常处理,截获异常,忽略或者终止程序处理异常 Python常见错误 常见错误:i