笨办法学Python记录--习题37 异常,lambda,yield,转义序列
习题中提到了raise,查了下,顺便所有异常类关键字罗列如下文章中:
为什么使用异常
错误处理、事件通知、特殊情况处理、退出时的行为、不正常的程序流程。
简单的示例
在没有任何定义x变量的时候:
print x
print 1将会抛出NameError异常:
NameError: name 'x' is not defined而且1并不会被输出,也就是说程序将被中断。如果讲代码修改如下:
try:
print x
exceptNameError:
print "Something is wrong!"
print 1得到的输出将是:
Something is wrong!
1可见,我们定义的except会“抓住”NameError类型的语句,并且执行相应的处理代码,而且程序不会被中断。
使用raise
我们可以自己触发异常,例如:
raise IndexErrorPython会返回:
Traceback (most recent call last):
File "d:\我的文档\桌面\todo\exep.py", line 1, in <module>
raise IndexError
IndexError自定义的异常
下面定义了一个MyException类,它继承自Python内置的Exception类。
class MyException(Exception):pass
try:
#some code here
raise MyException
except MyException:
print "MyException encoutered"结果为:
MyException encoutered可以在一个except内捕获多个异常:
except (AttributeError, TypeError, SyntaxError):捕获所有异常
只要在except后面不加任何异常类型,这个except块就可以捕获所有的异常。
except:捕获异常的继承关系
当我们except Super的时候,同样会捕获到raise Sub的异常。
finally
无论try块是否抛出异常,永远执行的代码。通常用来执行关闭文件,断开服务器连接的功能等等。
class MyException(Exception):pass
try:
#some code here
raise MyException
except MyException:
print "MyException encoutered"
finally:
print "Arrive finally"结果:
MyException encoutered
Arrive finallytry、except、else
可以在try块里加入else块,代码块将在没有异常被抛出的时候执行:
try:
print "normal code here"
except MyException:
print "MyException encoutered"
else:
print "No exception"
finally:
print "Arrive finally"结果为:
normal code here
No exception
Arrive finallyraise异常、同时添加数据
raise异常的同时,我们可以添加一些额外的数据,就像下面的例子一样:
class MyException(Exception):pass
try:
raise MyException,", and some additional data"
except MyException,data:
print "MyException encoutered"
print data断言assert
断言是指期望指定的条件满足,如果不满足则抛出AssertionError异常。例如:
def positive(x):
assert x > 0
print "x"
positive(1)
positive(0)positive(0)一句将会抛出一个异常。
with/as
with/as语句主要是为了代替try/finally语句、通常用来做一些善后工作或者是清理现场的工作。
with open('test.txt') as myfile:
for line in myfile:
#code here
#code here当with代码块结束之后,文件将会自动关闭。这是因为返回的对象支持context management protocol。原书598页有关于该协议的讨论,例如如何自定义一个支持该协议、从而支持with语句的类。
yield:貌似是个迭代常量的标记,详细参考“文章”里的一篇。
lambda函数介绍
在学习python的过程中,lambda的语法时常会使人感到困惑,lambda是什么,为什么要使用lambda,是不是必须使用lambda?
下面就上面的问题进行一下解答。
1、lambda是什么?
看个例子:
1 g = lambda x:x+1看一下执行的结果:
g(1)
>>>2
g(2)
>>>3
当然,你也可以这样使用:
lambda x:x+1(1)
>>>2
可以这样认为,lambda作为一个表达式,定义了一个匿名函数,上例的代码x为入口参数,x+1为函数体,用函数来表示为:
1 def g(x):
2 return x+1非常容易理解,在这里lambda简化了函数定义的书写形式。是代码更为简洁,但是使用函数的定义方式更为直观,易理解。
Python中,也有几个定义好的全局函数方便使用的,filter, map, reduce
>>> foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]
>>>
>>> print filter(lambda x: x % 3 == 0, foo)
[18, 9, 24, 12, 27]
>>>
>>> print map(lambda x: x * 2 + 10, foo)
[14, 46, 28, 54, 44, 58, 26, 34, 64]
>>>
>>> print reduce(lambda x, y: x + y, foo)
139上面例子中的map的作用,非常简单清晰。但是,Python是否非要使用lambda才能做到这样的简洁程度呢?在对象遍历处理方面,其实Python的for..in..if语法已经很强大,并且在易读上胜过了lambda。
比如上面map的例子,可以写成:
print [x * 2 + 10 for x in foo]
非常的简洁,易懂。
filter的例子可以写成:
print [x for x in foo if x % 3 == 0]
同样也是比lambda的方式更容易理解。
上面简要介绍了什么是lambda,下面介绍为什么使用lambda,看一个例子(来自apihelper.py):
processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)在Visual Basic,你很有可能要创建一个函数,接受一个字符串参数和一个 collapse 参数,并使用 if 语句确定是否压缩空白,然后再返回相应的值。这种方式是低效的,因为函数可能需要处理每一种可能的情况。每次你调用它,它将不得不在给出你所想要的东西之前,判断是否要压缩空白。在 Python 中,你可以将决策逻辑拿到函数外面,而定义一个裁减过的 lambda 函数提供确切的 (唯一的) 你想要的。这种方式更为高效、更为优雅,而且很少引起那些令人讨厌 (哦,想到那些参数就头昏) 的错误。
通过此例子,我们发现,lambda的使用大量简化了代码,使代码简练清晰。但是值得注意的是,这会在一定程度上降低代码的可读性。如果不是非常熟悉python的人或许会对此感到不可理解。
lambda 定义了一个匿名函数
lambda 并不会带来程序运行效率的提高,只会使代码更简洁。
如果可以使用for...in...if来完成的,坚决不用lambda。
如果使用lambda,lambda内不要包含循环,如果有,我宁愿定义函数来完成,使代码获得可重用性和更好的可读性。
总结:lambda 是为了减少单行函数的定义而存在的。
字符串转义序列:
\f 匹配一个换页符。等价于\x0c和\cL。
\v 匹配一个垂直制表符。等价于\x0b和\cK。
| 转义字符 | 描述 |
|---|---|
| \(在行尾时) | 续行符 |
| \\ | 反斜杠符号 |
| \’ | 单引号 |
| \” | 双引号 |
| \a | 响铃 |
| \b | 退格(Backspace) |
| \e | 转义 |
| \000 | 空 |
| \n | 换行 |
| \v | 纵向制表符 |
| \t | 横向制表符 |
| \r | 回车 |
| \f | 换页 |
| \oyy | 八进制数yy代表的字符,例如:\o12代表换行 |
| \xyy | 十进制数yy代表的字符,例如:\x0a代表换行 |
| \other | 其它的字符以普通格式输出 |
Python格式化字符串的替代符以及含义
| 符 号 | 说 明 |
| %c | 格式化字符及其ASCII码 |
| %s | 格式化字符串 |
| %d | 格式化整数 |
| %u | 格式化无符号整型 |
| %o | 格式化无符号八进制数 |
| %x | 格式化无符号十六进制数 |
| %X | 格式化无符号十六进制数(大写) |
| %f | 格式化浮点数字,可指定小数点后的精度 |
| %e | 用科学计数法格式化浮点数 |
| %E | 作用同%e,用科学计数法格式化浮点数 |
| %g | 根据值的大小决定使用%f活%e |
| %G | 作用同%g,根据值的大小决定使用%f活%e |
| %p | 用十六进制数格式化变量的地址 |
Python语言中的@符号有比较特殊的含义,而且是一种比较稀有的特性,初学者往往不容易理解,这里就其做一些解释。 首先看一段代码:
1 |
def minus(f): |
解释器首先会解释@符号后面的代码,如果如上面的代码类似,那么test(5)将被执行,因为test参数5大于3,所以会返回一个函数指针plus(可以用C的这个名字来理解),plus将下一行的函数指针xxx当作参数传入,直到执行完成。最后结果将输出‘plus’和‘ok’。 有时候可能是下面这种形式:
1 |
def minus(f): |
minus因为本身已经是一个函数指针,所以会直接以xxx作为参数传入,结果会输出‘minus’和‘ok’。
笨办法学Python记录--习题37 异常,lambda,yield,转义序列的更多相关文章
- 笨办法学Python记录--习题18 变量 函数 help的由来;if语句,循环和列表,冒泡排序,判断输入字符串的方法
20140414 记录 习题17 - 33 函数可以做3件事: 1. 给代码片段命名,,就跟“变量”给字符串和数字命名一样. 2. 可以接受参数,就跟你的脚本接受argv 一样. 3. 通过使用#1 ...
- 笨办法学Python记录--习题1-11
20140412(习题1-10),和打印较劲: 1. 读这本书时没有按照要求安装Python2,我选择的是最新版3.4.0(官方release),然后悲剧发现完全不兼容,现在摘录2,3区别: 这个星期 ...
- 笨办法学Python记录--习题15-17 开始读写文件啦
习题15 - 17 打开并读流程: from sys import argv script,filename = argv txt = open(filename) print "Here' ...
- 笨办法学Python记录--习题12-14 主要是pydoc用法,raw_input,argv
20140413 -- 习题12 - 14 1. pydoc在windows的用法,必须进入到python安装目录,执行Python -m pydoc raw_input; 网上给出了一个好玩的,不过 ...
- 笨办法学Python记录--习题38-40,复习前面,运用list操作函数
#习题38 区分列表和字符串,用到了split(字符串专用函数),join.append.pop(这些是list操作函数) ten_things = "Apples Oranges Crow ...
- 【笨办法学Python】习题11:打印出改变了的输入
print "How old are you?", age = raw_input() print "How tall are you?", height = ...
- 笨办法学Python - 习题1: A Good First Program
在windows上安装完Python环境后,开始按照<笨办法学Python>书上介绍的章节进行练习. 习题 1: 第一个程序 第一天主要是介绍了Python中输出函数print的使用方法, ...
- 笨办法学python - 专业程序员的养成完整版PDF免费下载_百度云盘
笨办法学python - 专业程序员的养成完整版PDF免费下载_百度云盘 提取码:xaln 怎样阅读本书 由于本书结构独特,你必须在学习时遵守几条规则 录入所有代码,禁止复制粘贴 一字不差地录入代码 ...
- 笨办法学Python 3|百度网盘免费下载|新手基础入门书籍
点击下方即可百度网盘免费提取 百度网盘免费下载:笨办法学Python 3 提取码:to27 内容简介: 本书是一本Python入门书,适合对计算机了解不多,没有学过编程,但对编程感兴趣的读者学习使用. ...
随机推荐
- DMA实验总结
一.RCC设置 没什么好写的之前USART的基本一样 /************************************************************************ ...
- UVA 10529 - Dumb Bones (概率dp)
题目描述 You are trying to set up a straight line of dominos, standing on end, to be pushed over later f ...
- Android中通过反射获取资源Id(特别用在自己定义一个工具将其打成.jar包时,特别注意资源的获取)
在将自己写的工具打成.jar包的时候,有时候会需要引用到res中的资源,这时候不能将资源一起打包,只能通过反射机制动态的获取资源. /** * 反射得到组件的id号 */ public static ...
- 用 GetEnvironmentVariable 获取常用系统环境变量
以前曾用 GetWindowsDirectory.GetSystemDirectory.GetTempPath 等函数获取系统常用文件夹; 也用过 SHGetSpecialFolderLocation ...
- VC++ 字符串操作学习总结
vc++中各种字符串(转载) http://www.cnblogs.com/tomin/archive/2008/12/28/1364097.html CString ,BSTR ,LPCTSTR之间 ...
- PLSQL连接虚拟机中的Oracle数据库
下面这个连接对以后虚拟机安装非常有用!!! https://blog.csdn.net/lixin5456985/article/details/81670095
- [NOIP模拟测试38]题解
来自达哥的问候…… A.金 显然本题的考察点在于高精而不是裴蜀定理 根据裴蜀定理易得答案为Yes当且仅当$gcd(n,m)=1$,那么考虑怎么在高精度下判互质. 如果$n,m$都能被2整除,那么显然不 ...
- 90、Tensorflow实现分布式学习,多台电脑,多个GPU 异步试学习
''' Created on 2017年5月28日 @author: weizhen ''' import time import tensorflow as tf from tensorflow.e ...
- python:TypeError: main() takes 0 positional arguments but 1 was given
TypeError: main() takes 0 positional arguments but 1 was given def main(self): 括号里加上self就好了
- Linux下JDK1.6升级1.8版本
先不管是否已安装JDK1.6还是JDK1.7,先下载 jdk-8u45-linux-x64.rpm 然后上传到 /usr/local/src 去.当然其他目录也可以.这里是默认位置 给所有用户 ...
