文章大纲
当开始规划程序时,对于这个具体的程序,还没有任何经验,在实现过程中,将逐渐有新的认识,后续可以利用这一点进行重构现有的软件。编写代码与编写文章一样,写作就是重写,要做好应对变化的准备。
Python 的灵活性有很多方面,此处只涉及到其中的两个:
- 原型设计
- 配置
原型设计
对程序的结构有一定想法后,建议实现一个功能可能极其有限的简单版本,有了可以运行的版本后,后续的工作将容易的很多,只需增加新的功能,或者到一定阶段进行重写即可。
有了原型后,是否推倒然后重新编写第二套程序?答案是不建议完全推倒重来,更好的选择应该是:对原型进行重构和修改,让其成为功能更好的系统。不建议的原因有:
- 第二系统综合征,永远没有完工的时候
- 不断重写综合征
- 代码疲劳症
配置
符号常量有助于提高程序抽象的程度。
提取常量
常量指的是内置的字面值,如数、字符串和列表。可以将其存储在全局变量中,而不在程序中反复输入它们。
符号常量遵循一种特殊的命名约定:只在变量名中使用大写字母并用下划线分隔单词。
配置文件
有些常量必须暴露给用户,可将这些配置变量放在独立的文件中,而不将它们放置在模块开头。
最简单的方式是专门为配置创建一个模块,如:
from config import PI
在 config
模块中导入 PI
符号常量。
另一种方法是使用标准库模块 configparser
,从而可在配置文件中使用标准格式。
一个简单的配置文件 area.ini
示例:
[numbers]
pi: 3.1415926
[messages]
greeting: Welcome to the area calculation program!
question: Please enter the radius:
result_message: The area is
一个使用 ConfigParser
的程序示例:
from configparser import ConfigParser
CONFIGFILE = "area.ini"
config = ConfigParser()
config.read(CONFIGFILE)
print(config['messages'].get('greeting'))
radius = float(input(config['messages'].get('question') + ' '))
print(config['messages'].get('result_message'), end=' ')
print(config['numbers'].getfloat('pi') * radius**2)
日志
日志有助于帮助发现问题和 Bug,日志就是收集与程序运行相关的数据,以供后续进行研究和分析。
print
语句是一种简单的日志形式:
log = open('logfile.txt', 'w')
print('Downloading file from URL', file=log)
print('File successfully downloaded', file=log)
但是当程序下载崩溃时,以上方法效果就很差,安全的做法是,在每条日志语句前后都打开或关闭文件,即使程序崩溃了,也可以看到日志文件的最后一行。
实际上日志推荐使用标准库中的 logging
模块。
使用 logging
模块的示例:
import logging
logging.basicConfig(level=logging.INFO, filename='app-log.log')
logging.info('Starting program')
logging.info('Trying to divide 1 by 0')
print(1/0)
logging.info('The division successed')
logging.info('Ending program')
运行后,app-log.log
中只有以下内容:
INFO:root:Starting program
INFO:root:Trying to divide 1 by 0
因为后续程序报错导致后面的语句没有执行。
通过合理的配置 logging
模块,日志可以按照所希望的方式记录:
- 记录不同类型的条目
- 只记录与程序特定部分相关的条目
- 记录有关时间、日期等方面的信息
- 记录到其它位置,如套接字
- 将一些日志过滤掉