原文发表在我的博客主页,转载请注明出处!

建议二十三:遵循异常处理的几点基本原则

python中常用的异常处理语法是try、except、else、finally,它们可以有多种组合,语法形式如下:

try:
<statements> # Run the main action first
except <name1>:
<statements> # 当try中发生name1的异常时处理
except <name2, name3>:
<statements> # 当try中发生name2或name3中的某一个异常的时候处理
except <name4> as <data>:
<statements> # 当try中发生name4的异常时处理,获取对应实例
except:
<statements> # 其他异常发生时处理
else:
<statements> # 没有异常发生时执行
finally:
<statements> # 不管有没有异常都会执行

异常处理通常需要遵循以下几点基本原则:

  • 注意异常的粒度,不推荐try中放入过多的代码
  • 谨慎使用单独的except语句处理所有异常,最好能定位具体的异常,同样最好不要使用except Exception或者except StandarError来捕获异常,通过一个例子来说明,上代码:
import sys
try:
print a
b = 0
print a/b
except:
sys.exit("ZeroDivisionError: Can not division zero")

执行代码,会打印ZeroDivisionError: Can not division zero,这会让我们以为是发生了除数为零的错误,但是修改下代码:

import sys
try:
print a
b = 0
print a/b
except ZeroDivisionError:
sys.exit("ZeroDivisionError: Can not division zero")

运行之后就会发现错误并不是因为除数为0,而是因为a在使用前没有定义。单独使用except会捕获包括SystemExit,KeyboardInterrupt等内在的各种异常,从而掩盖程序真正发生异常的原因,给debug造成一定的迷惑性。

  • 注意异常捕获的顺序,在合适的层次处理异常

    推荐的方法是将继承结构中子类异常在前面的except语句中抛出,而父类异常在后面的except语句抛出,因为当try块中有异常发生的时候,解释器根据except声明的顺序进行匹配,在第一个匹配的地方便立即处理该异常。
  • 使用更为友好的异常信息,遵守异常参数的规范,即提示的异常信息最好可以为用户和开发人员所理解

建议二十四:避免finally中可能发生的陷阱

finally语句经常被用来做一些清理工作,但使用finally时,要特别小心一些陷阱。

当try块中发生异常的时候,如果except语句中找不到对应的异常处理,异常将会被临时保存起来,当finally执行完毕的时候,临时保存的异常将会再次被抛出,但如果finally语句中产生了新的异常或者执行了return或者break语句,那么临时保存的异常将会被丢失,从而导致异常屏蔽。

另外如果在try和finally语句中同时存在return语句,最后返回的是finally中return的值,所以不推荐finally中使用return语句进行返回。


建议二十五:深入理解None,正确判断对象是否为空

python中以下数据会被当作空来处理:

  • 常量None
  • 常量False
  • 任何形式的数值类型零,如0,0L, 0.0, 0j
  • 空的序列,如‘’、()、[]
  • 空的字典:如{}
  • 当用户定义的类中定义了nonzero()方法和len()方法,并且该方法返回整数0或者布尔值False的时候。

其中常量None的特殊性体现在它既不是0、False,也不是空字符串,它就是一个空值对象。其数据类型为NoneType,遵循单例模式,是唯一的,因为不能创建None对象,所有赋值为None的变量都相等,并且None与任何其他非None的对象比较结果都为False。

判断列表是否为空的方式:

if list:
statements
else:
statements

上面代码执行过程会调用内部方法__nonzero__()来判断变量是否为空并返回结果。

nonzero():用于对自身对象进行控制测试,返回0/1或True/False。如果一个对象没有定义该方法,python将获取__len__()方法调用的结果来进行判断,如果一个类中既没有定义__len__()方法也没有定义__nonzero__()方法,该类的实例用if判断的结果都为True。


建议二十六:连接字符串应优先使用join而不是+

经过实验,join()方法的效率要高于+操作符,特别是字符串规模交大的时候。简述原理:

当用+连接字符串的时候,由于字符串是不可变对象,如果要连接字符串,执行一次+操作便会在内存中申请一块新的内存空间,并将上一次操作的结果和本次操作的右操作数复制到新申请的内存空间。

而join()方法会首先计算需要申请的总的内存空间,然后一次性申请所需内存并将字符串序列中的每一个元素复制到内存中去。


建议二十七:格式化字符串时尽量使用.format方式而不是%

先对两种格式化字符串方式做一个简单介绍:

%操作符根据转换说明符所规定的格式返回一串格式化后的字符串,转换说明符的基本形式为:

%[转换标记][宽度[.精确度]]

.format方法格式字符串的基本语法为:

[[填充符]对齐方式][符号][#][0][宽度][,][.精确度][转换类型]
#填充符是除了"{"和"}"符号以外的任意符号。

常用用法如下:

# 1.使用符号位置
"The number {0:,} in hex is: {0:#x}, the number {1} in oct is {1:#o}".format(4746, 45)
# 'The number 4,746 in hex is: 0x128a, the number 45 in oct is 0o55'
# 2.使用名称
print 'the max number is {max}, the min number is {min}, the average number is {average:0.3f}'.format(max=189,min=12.6,average=23.5)
# 'the max number is 189, the min number is 12.6, the average number is 23.500'
# 3.通过类的属性
# 4.格式化元组的具体项

尽量使用foramt的原因:

  • format方式比较灵活,参数的顺序与格式化的顺序不必完全相同
  • format方式可以方便地作为参数传递。即依靠python的灵活性,可以给format()传入参数进行处理
  • %最终会被.format方式取代
  • %方法在某些特殊情况下使用时需要特别小心,比如可以尝试下如下代码:
item = ('hh','xx')
print "item are %s" %(item)

参考:编写高质量代码--改善python程序的91个建议

编写高质量代码–改善python程序的建议(五)的更多相关文章

  1. 编写高质量代码--改善python程序的建议(六)

    原文发表在我的博客主页,转载请注明出处! 建议二十八:区别对待可变对象和不可变对象 python中一切皆对象,每一个对象都有一个唯一的标识符(id()).类型(type())以及值,对象根据其值能否修 ...

  2. 编写高质量代码--改善python程序的建议(八)

    原文发表在我的博客主页,转载请注明出处! 建议四十一:一般情况下使用ElementTree解析XML python中解析XML文件最广为人知的两个模块是xml.dom.minidom和xml.sax, ...

  3. 编写高质量代码--改善python程序的建议(七)

    原文发表在我的博客主页,转载请注明出处! 建议三十四:掌握字符串的基本用法 编程有两件事,一件是处理数值,另一件是处理字符串,在商业应用编程来说,处理字符串的代码超过八成,所以需要重点掌握. 首先有个 ...

  4. 编写高质量代码--改善python程序的建议(四)

    原文发表在我的博客主页,转载请注明出处! 建议十八:有节制的使用from...import语句 python提供了三种方式引入外部模块: import语句 from...import... __imp ...

  5. 编写高质量代码--改善python程序的建议(三)

    原文发表在我的博客主页,转载请注明出处! 建议十三:警惕eval()的安全漏洞 相信经常处理文本数据的同学对eval()一定是欲罢不能,他的使用非常简单: eval("1+1==2" ...

  6. 编写高质量代码–改善python程序的建议(二)

    原文发表在我的博客主页,转载请注明出处! 建议七:利用assert语句来发现问题断言(assert)在很多语言中都存在,它主要为调试程序服务,能够快速方便地检查程序的异常或者发现不恰当的输入等,可防止 ...

  7. 编写高质量代码--改善python程序的建议(一)

    原文发表在我的博客主页,转载请注明出处! 初衷 python是一个入门十分容易的编程语言,但是想要写好python却是一件不容易的事情,如果不是专业使用python的人,只是将python作为一个脚本 ...

  8. 编写高质量代码改善python程序91个建议学习01

    编写高质量代码改善python程序91个建议学习 第一章 建议1:理解pythonic的相关概念 狭隘的理解:它是高级动态的脚本编程语言,拥有很多强大的库,是解释从上往下执行的 特点: 美胜丑,显胜隐 ...

  9. 编写高质量代码 改善Python程序的91个建议 (读后 小记)

    此书是自己好久之前买的,当时总觉得Python语言中有各种trick, 总是要自己猝不及防的掉入到陷阱之中, 看了一些资料后发现了这本书,感觉很是不错,不过可惜自己平时总是杂事太多,总是找不到整块的时 ...

随机推荐

  1. DDL语句--改动表

    改动表是指改动数据库中已经存在的表的定义.改动表比又一次定义表简单.不须要又一次载入数据.也不会影响正在进行的服务. MySQL中通过ALTER TABLE语句来改动表.改动表包含改动表名.改动字段数 ...

  2. Asp.Net MVC项目通过Git同步到新开发设备上后无法作为网站启动

    右键项目名->属性->启动项目->单启动项目,在下拉框中选择你的网站主项目就可以了.(由于用的英文版,所以翻译的内容可能略有差异)

  3. 转载 :sql server分区 http://blog.itpub.net/27099995/viewspace-1081158/

    转载:http://blog.itpub.net/27099995/viewspace-1081158/ 在  sql server 2005 之前不提供分区表,但可以用其他方式建立“分区表”,sql ...

  4. Eclipse添加中文语言包与下载

    从Eclipse官网下载最新版本的Eclipse都是英文版的,不自带语言包.现在Eclipse有一个语言包项目,叫Eclipse Babel Project.如果需要语言包,可以联机从这儿下载. Ba ...

  5. Bash中的括号(二)

    双方括号[[]]的用法: 1.先举个例子说明: 假如你要再判断某个目录是否存在,又想当然写成: $ [ -f exists.txt && -d exists_folder ]; ech ...

  6. JAVA设计模式之 命令模式【Command Pattern】

    一.概述 命令模式能够将请求发送者和接收者全然解耦.发送者与接收者之间没有直接引用关系,发送请求的对象仅仅须要知道怎样发送请求,而不必知道怎样完毕请求.核心在于引入了命令类,通过命令类来减少发送者和接 ...

  7. 安装Eclipse插件长时间卡在 calculating requirements and dependencies

    把"Contact all update sites during install to find required software"前面的勾去掉,然后点击下一步,这样之后问题迎 ...

  8. Android App常规测试内容

    转自:https://mp.weixin.qq.com/s?__biz=MzU0NjcyNDg3Mw==&mid=2247484053&idx=1&sn=116fe8c7eed ...

  9. Qt 槽函数的使用

    今天在代码中遇到这样一个问题,自己感觉槽和函数都写的没错,但是就是不执行槽函数,因为是一个定时器的使用,即定时时间到了就执行槽函数. SeventhWizardPage::SeventhWizardP ...

  10. tail 命令详解

    tail 指令 功能:从指定点开始将文件写到标准输出.使用tail命令的-f选项可以方便的查阅正在改变的日志文件,tail -f filename会把filename里最尾部的内容显示在屏幕上,并且不 ...