Python基础篇【第3篇】: Python异常处理、反射、动态导入、利用反射的web框架
异常处理
什么是异常?
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
一般情况下,在Python无法正常处理程序时就会发生一个异常。异常是Python对象,表示一个错误。当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
方式一. 使用try/except语句。
try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。
如果你不想在异常发生时结束你的程序,只需在try里捕获它。
语法:
以下为简单的try....except...else的语法:
try:
<语句> #运行别的代码
except <名字>: #<名字>,表示异常类型。异常类型有很多种,下边会列出部分异常名称。
<语句> #如果在try部份引发了'name'异常
except <名字>,<数据>: #<数据>,表示将获取到的错误信息传递给<数据>,可以在进行输出
<语句> #如果引发了'name'异常,获得附加的数据
else:
<语句> #如果没有异常发生
try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。
该种异常处理语法的规则是:
- 执行try下的语句,如果引发异常,则执行过程会跳到第一个except语句。
- 如果第一个except中定义的异常与引发的异常匹配,则执行该except中的语句。
- 如果引发的异常不匹配第一个except,则会搜索第二个except,允许编写的except数量没有限制。
- 要是在当前函数里没有找到的话,它会将异常传递给上层的调用函数,看看那里能不能处理。
- 如果在最外层(全局“main”)还是没有找到的话,解释器就会退出,同时打印出traceback以便让用户找到错误产生的原因。
- 如果没有发生异常,则执行else块代码。
注意:
1. 虽然大多数错误会导致异常,但一个异常不一定代表错误,有时候它们只是一个警告,有时候它们可能是一个终止信号,比如退出循环等。
2. 使用except子句需要注意的事情,就是多个except子句截获异常时,如果各个异常类之间具有继承关系,则子类应该写在前面,否则父类将会直接截获子类异常。放在后面的子类异常也就不会执行到了。
常见异常类型:
异常名称 | 描述 |
---|---|
BaseException | 所有异常的基类 |
SystemExit | 解释器请求退出 |
KeyboardInterrupt | 用户中断执行(通常是输入^C) |
Exception | 常规错误的基类 |
StopIteration | 迭代器没有更多的值 |
GeneratorExit | 生成器(generator)发生异常来通知退出 |
StandardError | 所有的内建标准异常的基类 |
ArithmeticError | 所有数值计算错误的基类 |
FloatingPointError | 浮点计算错误 |
OverflowError | 数值运算超出最大限制 |
ZeroDivisionError | 除(或取模)零 (所有数据类型) |
AssertionError | 断言语句失败 |
AttributeError | 对象没有这个属性 |
EOFError | 没有内建输入,到达EOF 标记 |
EnvironmentError | 操作系统错误的基类 |
IOError | 输入/输出操作失败 |
OSError | 操作系统错误 |
WindowsError | 系统调用失败 |
ImportError | 导入模块/对象失败 |
LookupError | 无效数据查询的基类 |
IndexError | 序列中没有此索引(index) |
KeyError | 映射中没有这个键 |
MemoryError | 内存溢出错误(对于Python 解释器不是致命的) |
NameError | 未声明/初始化对象 (没有属性) |
UnboundLocalError | 访问未初始化的本地变量 |
ReferenceError | 弱引用(Weak reference)试图访问已经垃圾回收了的对象 |
RuntimeError | 一般的运行时错误 |
NotImplementedError | 尚未实现的方法 |
SyntaxError | Python 语法错误 |
IndentationError | 缩进错误 |
TabError | Tab 和空格混用 |
SystemError | 一般的解释器系统错误 |
TypeError | 对类型无效的操作 |
ValueError | 传入无效的参数 |
UnicodeError | Unicode 相关的错误 |
UnicodeDecodeError | Unicode 解码时的错误 |
UnicodeEncodeError | Unicode 编码时错误 |
UnicodeTranslateError | Unicode 转换时错误 |
Warning | 警告的基类 |
DeprecationWarning | 关于被弃用的特征的警告 |
FutureWarning | 关于构造将来语义会有改变的警告 |
OverflowWarning | 旧的关于自动提升为长整型(long)的警告 |
PendingDeprecationWarning | 关于特性将会被废弃的警告 |
RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
SyntaxWarning | 可疑的语法的警告 |
UserWarning | 用户代码生成的警告 |
所有异常都是基类Exception的成员。所有异常都从基类Exception继承,而且都在exceptions模块中定义。Python自动将所有异常名称放在内建命名空间中,所以程序不必导入exceptions模块即可使用异常。一旦引发而且没有捕捉SystemExit异常,程序执行就会终止。如果交互式会话遇到一个未被捕捉的SystemExit异常,会话就会终止。
例一:打开文件写入内容,没有异常
#!/usr/bin/python try:
fh = open("testfile", "w")
fh.write("This is my test file for exception handling!!")
except IOError:
print "Error: can\'t find file or read data"
else:
print "Written content in the file successfully"
fh.close() 返回结果:
Written content in the file successfully
例二:打开文件写入内容,有异常
#!/usr/bin/python try:
fh = open("testfile", "w")
fh.write("This is my test file for exception handling!!")
except IOError:
print "Error: can\'t find file or read data"
else:
print "Written content in the file successfully" 输出结果:
Error: can't find file or read data
我们这里输出的错误信息是我们手动进行定义的信息,我们能不能获取系统自己抛出的异常信息,并且输出呢?当然可以
异常信息参数获取
语法:
try:
You do your operations here;
......................
except ExceptionType, Argument:
print Argument #You can print value of Argument here...
举例
#!/usr/bin/python # Define a function here.
def temp_convert(var):
try:
return int(var)
except ValueError, Argument:
print "The argument does not contain numbers\n", Argument # Call above function here.
temp_convert("xyz"); 执行异常结果如下:
The argument does not contain numbers
invalid literal for int() with base 10: 'xyz'
方式二. 使用try/finally
语法:
try:
block
finally:
block
较正式说法:
执行try下的代码。
· 如果发生异常,在该异常传递到下一级try时,执行finally中的代码。
· 如果没有发生异常,则执行finally中的代码。
通俗式说法:我们不管线捕捉到的是什么错误,无论错误是不是发生,这些代码“必须”运行,比如文件关闭,释放锁,把数据库连接返还给连接池等。
注:这两种形式相互冲突,使用了一种就不允许使用另一种,而功能又各异
主动触发异常raise
我们可以使用raise语句自己触发异常
raise语法格式如下:
raise [Exception [, args [, traceback]]]
语句中Exception是异常的类型(例如,NameError)参数是一个异常参数值。该参数是可选的,如果不提供,异常的参数是"None"。
最后一个参数是可选的(在实践中很少使用),如果存在,是跟踪异常对象,后边简单介绍。
一个异常可以是一个字符串,类或对象。 Python的内核提供的异常,大多数都是实例化的类,这是一个类的实例的参数。
定义一个异常非常简单,如下所示:
def functionName( level ):
if level < 1:
raise "Invalid level!", level
# The code below to this would not be executed
# if we raise the exception
注意:为了能够捕获异常,"except"语句必须有用相同的异常来抛出类对象或者字符串。
例如我们捕获以上异常,"except"语句如下所示:
try:
Business Logic here...
except "Invalid level!":
Exception handling here...
else:
Rest of the code here...
traceback(跟踪)模块查看异常
发生异常时,Python能“记住”引发的异常以及程序的当前状态。Python还维护着traceback(跟踪)对象,其中含有异常发生时与函数调用堆栈有关的信息。记住,异常可能在一系列嵌套较深的函数调用中引发。程序调用每个函数时,Python会在“函数调用堆栈”的起始处插入函数名。一旦异常被引发,Python会搜索一个相应的异常处理程序。如果当前函数中没有异常处理程序,当前函数会终止执行,Python会搜索当前函数的调用函数,并以此类推,直到发现匹配的异常处理程序,或者Python抵达主程序为止。这一查找合适的异常处理程序的过程就称为“堆栈辗转开解”(Stack Unwinding)。解释器一方面维护着与放置堆栈中的函数有关的信息,另一方面也维护着与已从堆栈中“辗转开解”的函数有关的信息。
用户自定义异常
通过创建一个新的异常类,程序可以命名它们自己的异常。异常应该是典型的继承自Exception类,通过直接或间接的方式。
以下为与RuntimeError相关的实例,实例中创建了一个类,基类为RuntimeError,用于在异常触发时输出更多的信息。
在try语句块中,用户自定义的异常后执行except块语句,变量 e 是用于创建Networkerror类的实例。
class Networkerror(RuntimeError):
def __init__(self, arg):
self.args = arg
在你定义以上类后,你可以触发该异常,如下所示:
try:
raise Networkerror("Bad hostname")
except Networkerror,e:
print e.args
断言
使用assert断言是学习python一个非常好的习惯,python assert 断言句语格式及用法很简单。在没完善一个程序之前,我们不知道程序在哪里会出错,与其让它在运行最崩溃,不如在出现错误条件时就崩溃,这时候就需要assert断言的帮助。
python assert断言是声明其布尔值必须为真的判定,如果发生异常就说明表达示为假。可以理解assert断言语句为raise-if-not,用来测试表示式,其返回值为假,就会触发异常。
1、assert语句用来声明某个条件是真的。
2、如果你非常确信某个你使用的列表中至少有一个元素,而你想要检验这一点,并且在它非真的时候引发一个错误,那么assert语句是应用在这种情形下的理想语句。
3、当assert语句失败的时候,会引发一AssertionError。
反射
有时候我们会碰到这样的需求,需要执行对象的某个方法,或是需要对对象的某个字段赋值,而方法名或是字段名在编写代码时并不能确定,需要通过参数传递字符串的形式输入。这个机制被称为反射(反过来让对象告诉我们他是什么),或是自省,用于实现在运行时获取未知对象的信息。反射是个很吓唬人的名词,听起来高深莫测,在一般的编程语言里反射相对其他概念来说稍显复杂,一般来说都是作为高级主题来讲;但在Python中反射非常简单,用起来几乎感觉不到与其他的代码有区别,使用反射获取到的函数和方法可以像平常一样加上括号直接调用,获取到类后可以直接构造实例;不过获取到的字段不能直接赋值,因为拿到的其实是另一个指向同一个地方的引用,赋值只能改变当前的这个引用而已。
说人话版:当我们拥有一个对象或者类或者模块时,不知道有哪些属性时,我们就可以使用反射来进行判断,获取,添加等操作。说到这里的属性,我们就要参考类属性概念。这里的属性并不局限于类属性,只要是能调用到的,都可以认为是属性。
dir([obj]):
调用这个方法将返回包含obj大多数属性名的列表(会有一些特殊的属性不包含在内)。obj的默认值是当前的模块对象。
hasattr(obj, attr): 检查是否有这个属性
这个方法用于检查obj是否有一个名为attr的值的属性,返回一个布尔值。
getattr(obj, attr): 获取属性,实际上获取到的是属性的内存地址,加()就是获取属性对应的方法
作用:返回object的名称为name的属性的属性值,如果属性name存在,则直接返回其属性值;如果属性name不存在,则触发AttribetError异常或当可选参数default定义时返回default值。
setattr(obj, attr, val):可理解为属性赋值作用:
设置object的名称为name(type:string)的属性的属性值为value,属性name可以是已存在属性也可以是新属性。
delattr(object, name)
中文说明:删除object对象名为name的属性。这个函数的命名真是简单易懂啊,和jquery里面差不多,但是功能不一样哦,注意一下。
参数object:对象。
参数name:属性名称字符串。
版本:各版本中都支持该函数,python3中仍可用。
英文说明:This is a relative of setattr(). The arguments are an object and a string. The string must be the name of one of the object’s attributes. The function deletes the named attribute, provided the object allows it. For example, delattr(x, 'foobar') is equivalent to del x.foobar.
反射操作多层嵌套成员
直接举例
name = "xiaoming" def test():
pass class dev:
def show():
print "hello"
就想上边的代码一样,我们可以使用getattr获取的属性有:
cls = getattr(exp,"test")
print cls
s_name =getattr(cls,"show")
print s_name
结果为:
exp.test
hello
可见,我们可以使用getattr进行多层的属性反射。
利用反射进行动态模块导入
实例
controller,action = raw_input('URL:').split('/')
module = __import__(controller) #这句话就相当于import controller as module
func = getattr(module,action)
ret = func()
print ret
这样就实现了动态导入某个模块信息的作用。具体参考上课视频day14 动态模块导入
利用反射的web框架
在学习了反射以后,我们就可以引申到理解web框架[网页目录结构],我们可以将整个网站的所有目录认为是一个个Python包,在寻找文件或者文件内容中的函数时,就可以利用反射的方法进行查找。而这也正是所有框架的设计原理。具体信息以后我们再进行具体解释。
Python基础篇【第3篇】: Python异常处理、反射、动态导入、利用反射的web框架的更多相关文章
- Python 实现抽象类的两种方式+邮件提醒+动态导入模块+反射(参考Django中间件源码)
实现抽象类的两种方式 方式一 from abc import ABCMeta from abc import abstractmethod class BaseMessage(metaclass=AB ...
- Python基础之【第一篇】
Python简介: python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语 ...
- Python 基础【第八篇】变量
1.变量定义: 给数据进行命名,数据的名字就叫做变量 2.变量格式: [变量名] = [值] 注:变量名命名需要满足下面两条准则 准则一:标示符开头不能为数字.不能包含空格.特殊字符准则二:标示符不能 ...
- python基础19 -------面向对象终结篇(介绍python对象中各种内置命令)
一.isinstance()和issubclass()命令 1.isinstance(对象,类型) 用来判定该对象是不是此类型或者说是该对象是不是此类的对象,返回结果为True和False,如图所示. ...
- python基础【第四篇】
python第二节 1.while循环 Python 编程中 while 语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务.基本形式为: while 条件: 循环体 ...
- Python基础【day01】:python介绍发展史(一)
本节内容 Python介绍 发展史 Python 2 or 3? 一. Python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏 ...
- 『Python基础』第2节: Python简介及入门
一. Python介绍 Python是一门高级计算机程序设计语言,1989年,荷兰的Guido von Rossum创造了它.Guido是是一个牛人,1982年,他从阿姆斯特丹大学获得了数学和计算机硕 ...
- Python基础【day01】:python 2和3区别(四)
许多Python初学者都会问:我应该学习哪个版本的Python.对于这个问题,我的回答通常是“先选择一个最适合你的Python教程,教程中使用哪个版本的Python,你就用那个版本.等学得差不多了,再 ...
- (Python基础教程之十三)Python中使用httplib2 – HTTP GET和POST示例
Python基础教程 在SublimeEditor中配置Python环境 Python代码中添加注释 Python中的变量的使用 Python中的数据类型 Python中的关键字 Python字符串操 ...
- python基础(2):python的变量和常量
今天看看python的变量和常量:python3 C:\test.py 首先先说一下解释器执行Python的过程: 1. 启动python解释器(内存中) 2. 将C:\test.py内容从硬盘读入内 ...
随机推荐
- Query 一些简单的效果
Query 一些简单的效果 $(selector).hide(speed,callback); 隐藏 $(selector).show(speed,callback); 显示 $(selector). ...
- SecWeek
“叮铃铃,叮铃铃”清晨闹钟如期而至,每天的这个时候都会是一天中最头痛的时刻,每日坚持早起,渐渐已经开始习惯,扶着沉重的额头,侧身翻起,会觉得世界都在天旋地转. 一个人,悄悄的开门,悄悄的刷牙洗脸,然后 ...
- vs增加第三方依赖库的方法总结
转自http://blog.csdn.net/raodotcong/article/details/8998379 先说说普通的两种方法: 方法1: 通过设置工程配置来添加lib库. 转自网上: A ...
- AJAX跨域
AJAX跨域AJAX不允许跨域访问. 跨域是指浏览器B显示的是服务器S1的数据,全是从S1取得的数据则是同域:但如果B显示的S1上的数据的某个比如img是从S2上取得的数据,则是跨域.端口不一样也是跨 ...
- CSS样式--实际开发总结
1. div 嵌套,子div中内容超出范围可以设置: display:inline-block; overflow:auto 即可让子div中出现滚轴 2. 让div中内容垂直方向居中 设置: ...
- [C# WPF]MoeEroViewer Developing Log
[C# WPF]MoeEroViewer Developing Log 1st - Base Document run on Https://github.com/Amarillys/MoeEroVi ...
- centos6.3环境下升级python及MySQLdb的安装
近来突然想鼓捣下linux下的python,看下Python数据库方面的东西,想着在centos下测试下.然而安装的过程有很多坑.下面对整个流程进行下记录 1.python基本库的安装 在安装pyth ...
- 集群 & 负载均衡
集群(Cluster) 指一组计算机系统构成一个松耦合的多处理器系统,它们之间通过网络实现进程间的通信,实现分布式计算.在客户端看来就像是只有一个服务器.集群可以利用多个计算机进行并行计算从而获得很高 ...
- C#编程总结(十四)dynamic
http://www.cnblogs.com/yank/p/4177619.html C#编程总结(十四)dynamic 介绍 Visual C# 2010 引入了一个新类型 dynamic. 该类型 ...
- mybatis 与 缓存
首先从配置文件说起,有个cacheEnabled的配置项,当设置为true时(默认就是true),Session就会用一个CachingExecutor来包装我们的Executor实例: public ...