编写高质量代码--改善python程序的建议(四)
原文发表在我的博客主页,转载请注明出处!
建议十八:有节制的使用from...import语句
python提供了三种方式引入外部模块:
- import语句
 - from...import...
 - __import__函数
 
使用的时候需要注意以下几点:
- 一般情况下尽量优先使用import a形式,如访问B时需要使用a.B的形式
 - 有节制地使用from a import B形式,可以直接访问B
 - 尽量避免使用from a import *,因为这会污染命名空间,并且无法清晰地表示导入了哪些对象
 
首先简单的了解下python的import机制。python在初始化运行环境的时候会预先加载一批内建模块到内存中,这些模块相关的信息被存放在sys.modules中,当加载一个模块的时候,解释器世嘉尚要完成以下动作:
- 在sys.modules中进行搜索看看该模块是否已经存在,如果存在,则将其导入到当前局部命名空间,加载结束
 - 如果在sys.modules中找不到对应模块的名称,则为需要导入的模块创建一个字典对象,并将该对象信息插入sys.modules中
 - 加载前确认是否需要对模块对应的文件进行编译,如果需要则先进行编译
 - 执行动态加载,在当前模块的命名空间中执行编译后的字节码,并将其中所有的对象放入模块对应的字典中。
 
如果无节制的使用from a import ...会带来以下问题:
- 命名空间冲突
一般来说在非常明确不会造成明明冲突的前提下,以下几种情况下可以考虑使用from...import语句 - 当只需要导入部分属性或方法时
 - 模块中的这些属性和方法访问频率较高导致使用“模块名.名称”的形式进行访问过于繁琐时
 - 模块的文档明确说明需要使用from..import形式,导入的是一个包下面的子模块,且能够更为简单和便利时
 - 循环嵌套导入的问题
 
c1.py:
from c2 import g
def x():
	pass
c2.py:
from c1 import x
def g():
	pass
有时间可以试试上面的导入,会抛出ImportError异常,但是直接使用import就可以。
建议十九:优先使用absolute import来导入模块
相对导入:在不指明package名的情况相爱导入自己这个package的模块
绝对导入:指明顶层package名,python会在sys.path中寻找所有的顶层模块
加入有如下文件结构,其中app/sub1/string.py中定义了一个lower()方法。
app/
  __init__.py
  sub1/
	__init__.py
	mod1.py
	string.py
  sub2/
	__init__.py
	mod2.py
经验告诉我们,挡在mod1.py中import string之后,调用string.lower()方法时,会覆盖掉python自带的string模块中的方法。所以如果要使用python的String模块中的方法呢?
python2.5后为absolute import提供了一种新的机制,在模块中使用from _future_ import absolute_import语句进行说明后再进行导入,会禁用implicit relative,但是并不会禁掉explicit relative import。同时类似于linux,它还通过点号提供了一种显式进行relative import的方法,“.”表示当前目录,“..”表示当前目录的上一层目录。
相比于absolute import,relative import的问题比较多,因此推荐优先使用absolute import。
建议二十:i+=1 不等于 ++i
python的解释器会将++i操作解释为+(+i),其中+号表示证书符号,--i也类似。
建议二十一:使用with自动关闭资源
with语句的语法为:
with exp1 [as target]:
	code... 
#嵌套
with expr1 as e1:
	with expr2 as e2
等价于
with expr1 as e1, expr2 as e2
with语句可以在代码块执行完毕后进入该代码块时的现场,执行过程如下:
- 计算表达式的值,返回一个上下文管理器对象
 - 加载上下文管理器对象的__exit__()方法以备后用
 - 调用上下文管理器对象的__enter__()方法
 - 如果with语句中设置了目标对象,则将__enter__()方法的返回值复制给目标对象
 - 执行with中的代码块
 - 如果步骤5中代码正常结束,调用上下文管理器对象的__exit__()方法,其返回值忽略
 - 如果步骤5中代码执行过程中发生异常,调用上下文管理器对象的__exit__()方法,并将异常类型、值及traceback信息作为参数传递给__exit__()方法,如果__exit__()返回值为false,则异常值会被重新抛出;否则挂起异常,程序继续执行。
 
上下文管理器:用来创建一个运行时的环境,是一个对象,定义程序运行时需要建立的上下文,处理程序的进入和退出,实现了上下文管理协议,即在对象中定义了__enter__()和__exit__()方法:
- enter():进入运行时的上下文,返回运行时上下文相关的对象
 - exit(exception_type, exception_value, traceback):退出运行时的上下文,定义在块执行(或终止)之后上下文管理器应该做什么。
 
建议二十二:使用else子句简化循环(异常处理)
在python中,不仅分支语句有else子句,循环语句和异常处理也有。
首先看循环语句中的else,语法为:
#while循环
"while" expre ":" suite
["else" ":" suite]
#for循环
"for" target_list "in" expre_list ":" suite
["else" ":" suite]
具体不再赘述,下面两端代码具有同样的功能,可以进行比较。
def print_prime(n):
	for i in xrange(2, n):
		found = True
		for j in xrange(2, i):
			if i % j == 0:
				found = False
				break
		if found:
			print i
def print_prime2(n):
	for i in xrange(2, n):
		for j in xrange(2, i):
			if i % j == 0:
				break
		else:
			print i
和循环语句中的else相似,异常处理也提供了else子句语法,直接看例子
def save(db, obj):
	try:
		db.execute('a sql stmt', obj.attr1)
		db.execute('another sql stmt', obj.attr2)
	except DBError:
		db.rollback()
	esle:
		db.commit()
def save(db, obj):
	some_error_occured = False
	try:
		db.execute('a sql stmt', obj.attr1)
		db.execute('another sql stmt', obj.attr2)
	except DBError:
		db.rollback()
		some_error_occurred = True
	if not some_error_occured:
		db.commit()
总结:本篇列举了python的一些基础语法使用建议和注意事项,慢慢消化
参考:编写高质量代码--改善python程序的91个建议
编写高质量代码--改善python程序的建议(四)的更多相关文章
- 编写高质量代码--改善python程序的建议(六)
		
原文发表在我的博客主页,转载请注明出处! 建议二十八:区别对待可变对象和不可变对象 python中一切皆对象,每一个对象都有一个唯一的标识符(id()).类型(type())以及值,对象根据其值能否修 ...
 - 编写高质量代码--改善python程序的建议(八)
		
原文发表在我的博客主页,转载请注明出处! 建议四十一:一般情况下使用ElementTree解析XML python中解析XML文件最广为人知的两个模块是xml.dom.minidom和xml.sax, ...
 - 编写高质量代码--改善python程序的建议(七)
		
原文发表在我的博客主页,转载请注明出处! 建议三十四:掌握字符串的基本用法 编程有两件事,一件是处理数值,另一件是处理字符串,在商业应用编程来说,处理字符串的代码超过八成,所以需要重点掌握. 首先有个 ...
 - 编写高质量代码–改善python程序的建议(五)
		
原文发表在我的博客主页,转载请注明出处! 建议二十三:遵循异常处理的几点基本原则 python中常用的异常处理语法是try.except.else.finally,它们可以有多种组合,语法形式如下: ...
 - 编写高质量代码--改善python程序的建议(三)
		
原文发表在我的博客主页,转载请注明出处! 建议十三:警惕eval()的安全漏洞 相信经常处理文本数据的同学对eval()一定是欲罢不能,他的使用非常简单: eval("1+1==2" ...
 - 编写高质量代码–改善python程序的建议(二)
		
原文发表在我的博客主页,转载请注明出处! 建议七:利用assert语句来发现问题断言(assert)在很多语言中都存在,它主要为调试程序服务,能够快速方便地检查程序的异常或者发现不恰当的输入等,可防止 ...
 - 编写高质量代码--改善python程序的建议(一)
		
原文发表在我的博客主页,转载请注明出处! 初衷 python是一个入门十分容易的编程语言,但是想要写好python却是一件不容易的事情,如果不是专业使用python的人,只是将python作为一个脚本 ...
 - 编写高质量代码改善python程序91个建议学习01
		
编写高质量代码改善python程序91个建议学习 第一章 建议1:理解pythonic的相关概念 狭隘的理解:它是高级动态的脚本编程语言,拥有很多强大的库,是解释从上往下执行的 特点: 美胜丑,显胜隐 ...
 - 编写高质量代码 改善Python程序的91个建议    (读后 小记)
		
此书是自己好久之前买的,当时总觉得Python语言中有各种trick, 总是要自己猝不及防的掉入到陷阱之中, 看了一些资料后发现了这本书,感觉很是不错,不过可惜自己平时总是杂事太多,总是找不到整块的时 ...
 
随机推荐
- Linux 文件系统类型 文件系统结构 与Windows文件系统的比较
			
摘自:http://blog.csdn.net/gelivable007/article/details/7249365 Linux 文件系统类型 磁盘文件系统.包括硬盘.CD-ROM.DVD.USB ...
 - angular过滤器使用 自定义过滤器
			
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script sr ...
 - 已知的问题:本文总结了与Telerik UI for ASP.NET Core相关的所有已知问题。
			
ASP.NET Core Framework 不支持数据表. 有关此限制的更多信息,请参阅dotnet / corefx#1039. 不支持本地化资源. 有关此限制的更多信息,请参阅dotnet / ...
 - Lintcode---线段树查询(区间最大值)
			
对于一个有n个数的整数数组,在对应的线段树中, 根节点所代表的区间为0-n-1, 每个节点有一个额外的属性max,值为该节点所代表的数组区间start到end内的最大值. 为SegmentTree设计 ...
 - server2008系统修改3389远程端口
			
我给大家简单谈谈正确修改远程端口的方法 在开始-----运行菜单里,输入regedit,进入注册表编辑,按先面的路径进入修改端口的地方 HKEY_LOCAL_MACHINE\System ...
 - PHP系统学习1
			
1.php变量 2.php引用变量 $name1=&$name2; 3.全局变量 4.魔术变量__LINE__,__FILE__,__FUNCTION__,__CLASS__,__METHOD ...
 - (1)Smali系列学习之Smali函数调用语句分析
			
一.函数调用smali中的函数和成员变量也分为两种,分别为 direct 和 virtual.两者的区别如下: 1.direct method 是指调用private方法.2.virtual meth ...
 - JSP中out.write()和out.print()的区别
			
out对象的类型是JspWriter.JspWriter继承了java.io.Writer类. 1)print方法是子类JspWriter,write是Writer类中定义的方法: 2)重载的prin ...
 - SpringBoot入门系列:第三篇 日志输出
			
http://blog.csdn.net/lxhjh/article/details/51752419
 - oracle数据库访问order by不起作用分析
			
`SELECT * FROM student ROWNUM <= 1 ORDER BY id ASC`执行结果,返回结果没有排序.使用驱动"System.Data.OracleClie ...