- Preface 前言
- 第1章 引论
- 第2章 编程惯用法
- 第3章 基础语法
- 建议19:有节制地使用 from…import 语句
- 建议20:优先使用 absolute import 来导入模块
- 建议21:i+=1 不等于 ++i
- 建议22:使用 with 自动关闭资源
- 建议23:使用 else 子句简化循环(异常处理)
- 建议24:遵循异常处理的几点基本原则
- 建议25:避免 finally 中可能发生的陷阱
- 建议26:深入理解 None 正确判断对象是否为空
- 建议27:连接字符串应优先使用 join 而不是 +
- 建议28:格式化字符串时尽量使用 .format 方式而不是 %
- 建议29:区别对待可变对象和不可变对象
- 建议30:[]、() 和 {}:一致的容器初始化形式
- 建议31:记住函数传参既不是传值也不是传引用
- 建议32:警惕默认参数潜在的问题
- 建议33:慎用变长参数
- 建议34:深入理解 str() 和 repr() 的区别
- 建议35:分清 staticmethod 和 classmethod 的适用场景
- 第4章 库
- 建议36:掌握字符串的基本用法
- 建议37:按需选择 sort() 或者 sorted()
- 建议38:使用 copy 模块深拷贝对象
- 建议39:使用 Counter 进行计数统计
- 建议40:深入掌握 ConfigParser
- 建议41:使用 argparse 处理命令行参数
- 建议42:使用 pandas 处理大型 CSV 文件
- 建议43:一般情况使用 ElementTree 解析 XML
- 建议44:理解模块 pickle 优劣
- 建议45:序列化的另一个不错的选择 JSON
- 建议46:使用 traceback 获取栈信息
- 建议47:使用 logging 记录日志信息
- 建议48:使用 threading 模块编写多线程程序
- 建议49:使用 Queue 使多线程编程更安全
- 第5章 设计模式
- 第6章 内部机制
- 建议54:理解 built-in objects
- 建议55:init() 不是构造方法
- 建议56:理解名字查找机制
- 建议57:为什么需要 self 参数
- 建议58:理解 MRO 与多继承
- 建议59:理解描述符机制
- 建议60:区别 getattr() 和 getattribute() 方法
- 建议61:使用更为安全的 property
- 建议62:掌握 metaclass
- 建议63:熟悉 Python 对象协议
- 建议64:利用操作符重载实现中缀语法
- 建议65:熟悉 Python 的迭代器协议
- 建议66:熟悉 Python 的生成器
- 建议67:基于生成器的协程及 greenlet
- 建议68:理解 GIL 的局限性
- 建议69:对象的管理与垃圾回收
- 第7章 使用工具辅助项目开发
- 第8章 性能剖析与优化
建议40:深入掌握 ConfigParser
几乎所有的应用程序真正运行起来的时候,都会读取一个或几个配置文件。配置文件的意义在于用户不需要修改代码,就可以改变应用程序的行为,让它更好地为应用服务。比如pylint就带有一个参数--rcfile用以指定配置文件,实现对自定义代码风格的检测。常见的配置文件格式有XML和ini等,其中在MS Windows系统上,ini文件格式用得尤其多,甚至操作系统的API也都提供了相关的接口函数来支持它。类似ini的文件格式,在Linux等操作系统中也是极常用的,比如pylint的配置文件就是这个格式。但凡这种常用的东西,Python都有个标准库来支持它,也就是ConfigParser。
ConfigParser的基本用法通过手册可以掌握,但是仍然有几个知识点值得在这里跟大家说一下。首先就是getboolean()这个函数。getboolean()根据一定的规则将配置项的值转换为布尔值,如以下的配置:
[section1] option1=0
当调用getboolean('section1', 'optioin1')时,将返回False。不过getboolean()的真值规则值得一说:除了0之外,no、false和off都会被转义为False,而对应的1、yes、true和on则都被转义为True,其他值都会导致抛出ValueError异常。这样的设计非常贴心,使得我们能够在不同的场合使用yes/no、true/false、on/off等更切合自然语言语法的词汇,提升配置文件的可维护性。
除了getboolean()之外,还需要注意的是配置项的查找规则。首先,在ConfigParser支持的配置文件格式里,有一个[DEFAULT]节,当读取的配置项在不在指定的节里时,ConfigParser将会到[DEFAULT]节中查找。举个例子,有如下配置文件:
$ cat example.conf [DEFAULT] in_default = 'an option value in default' [section1]
简单地编写一段程序尝试通过section1获取in_default的值。
$ cat readini.py import ConfigParser conf = ConfigParser.ConfigParser() conf.read('example.conf') print conf.get('section1', 'in_default')
运行结果如下:
$ python readini.py 'an option value in default'
可见ConfigParser的行为跟上文描述是一致的。不过,除此之外,还有一些机制导致项目对配置项的查找更复杂,这就是class ConfigParser构造函数中的defaults形参以及其get(section, option[, raw[, vars]])中的全名参数vars。如果把这些机制全部用上,那么配置项值的查找规则如下:
1)如果找不到节名,就抛出NoSectionError。
2)如果给定的配置项出现在get()方法的vars参数中,则返回vars参数中的值。
3)如果在指定的节中含有给定的配置项,则返回其值。
4)如果在[DEFAULT]中有指定的配置项,则返回其值。
5)如果在构造函数的defaults参数中有指定的配置项,则返回其值。
6)抛出NoOptionError。
因为篇幅所限,这里就不提供示例了,大家可以自行构造相应的例子来验证。接下来要讲的是第三个特点。大家知道,在Python中字符串格式化可以使用以下语法:
>>> '%(protocol)s://%(server)s:%(port)s/' % { 'protocol':'http', 'server':'example.com', 'port':1080} 'http://example.com:1080/'
其实ConfigParser支持类似的用法,所以在配置文件中可以使用。如,有如下配置选项:
$ cat format.conf [DEFAULT] conn_str = %(dbn)s://%(user)s:%(pw)s@%(host)s:%(port)s/%(db)s dbn = mysql user = root host=localhost port = 3306 [db1] user = aaa pw=ppp db=example [db2] host=192.168.0.110 pw=www db=example
这是一个很常见的SQLAlchemy应用程序的配置文件,通过这个配置文件能够获取不同的数据库配置相应的连接字符串,即conn_str。如你所见,conn_str定义在[DEFAULT]中,但当它通过不同的节名来获取格式化后的值时,根据不同配置,得到不同的值。先来看以下代码:
$ cat readformatini.py import ConfigParser conf = ConfigParser.ConfigParser() conf.read('format.conf') print conf.get('db1', 'conn_str') print conf.get('db2', 'conn_str')
非常简单的代码,就是通过ConfigParser获取db1和db2两个节的配置。然后看如下输出:
$ python readformatini.py mysql://aaa:ppp@localhost:3306/example mysql://root:www@192.168.0.110:3306/example
可以看到,当通过不同的节名调用get()方法时,格式化conn_str的参数是不同的,这个规则跟上述查找配置项的规则相同。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论