最新消息:欢迎光临 魔力 • Python!大家可以点开导航菜单中的【学习目录】,这个目录类似图书目录,更加方便学习!

Python3萌新入门笔记(53)

Python教程 小楼一夜听春语 5032浏览 0评论

这一篇教程,我们一起来了解Python编程中有关配置、日志和测试的内容。

有关这些内容,对于大多数人来说并不常用。

所以,我觉得只要有一些了解就可以了。

真正提高到一定水平的时候,再去深入学习也为时不晚。

在入门阶段,没有必要因为这些暂时无用的内容对学习造成负担。

一、配置

读取配置文件,我们这里使用configparser模块。

首先,我们来看一下配置文件的格式。

创建配置文件,可以通过一个文本文档来创建,或者在PyCharm的文件(File)菜单中新建(New)一个文件(File)。

配置文件的扩展名可以自定义,一般可以用“.ini”作为后缀,表示该文件是初始化文件(Initialization File)。

配置文件中类别的格式为:[类别名称]

配置项与其对应的值可以有两种格式:

  • 配置项的名称 : 值
  • 配置项的名称 = 值

配置文件内容示例:

[Size]
height : 768
width : 1024

[Color]

background = 白色
border = 黑色

上面的配置文件包含了两个类别“Size”和“Color”,每个类别中都有两个配置项,采用两种不同的格式设置了对应的值。

接下来,我们就可以通过configparser模块来读取配置文件的信息。

示例代码:

import configparser  # 导入模块

file = 'config.ini'  # 指定文件路径
config = configparser.ConfigParser()  # 实例化配置解析的类
config.read(file,encoding='utf-8')  # 读取配置文件内容
print('程序界面宽度:', config.get('Size', 'width'))  # 获取某一项配置的值
print('程序界面高度:', config.get('Size', 'height'))  # 获取某一项配置的值
print('程序界面背景颜色:', config.get('Color', 'background'))  # 获取某一项配置的值
print('程序界面边框颜色:', config.get('Color', 'border'))  # 获取某一项配置的值

一般来说,配置文件是给程序的使用者使用的,比如通过配置文件更改图形界面程序的皮肤,或者通过配置文件隐藏显示某些功能等等。

二、测试

有一种开发方法叫测试驱动开发(Test-Driven Development)。

测试驱动开发的基本思想就是在开发功能代码之前,先编写测试代码,然后只编写使测试通过的功能代码,从而以测试来驱动整个开发过程的进行。

关于这种开发方法的具体细节,不是一两句话就能说清楚的。

大家可以参考一下IBM在线开发者社区中的这篇文章《浅谈测试驱动开发(TDD)》。

测试一点代码,编写一点代码,可能不太好理解。

实际上,在测试代码中是要考虑到功能代码完成什么样的功能,以及种种可能出现的问题。

这样就规范了功能代码的实现范围,并且避免功能代码可预见问题的出现。

1、文档测试

文档测试需要使用doctest模块。

它可以通过代码文档中的交互式环境操作内容进行测试。

示例代码:

import doctest
'''
'>>>' 开头的行为测试用例,测试用例的下一行为测试用例的结果。
'''
def perimeter(r):
    '''
    计算圆形的周长。
    :param r: 圆形半径的数值
    :return: 圆形的周长
    >>> perimeter(3)
    18.85
    '''
    return round(2 * 3.14159 * r, 2)

if __name__ == '__main__':
    doctest.testmod()  # 运行测试

在上方代码中,我们能够看到perimeter()函数的文档中有如下两句:

>>> perimeter(3)
18.85

这两句内容就是我们在交互式环境中,调用perimeter()函数并传入参数的操作以及正确的结果。

doctest模块能够获取到这部分内容,执行测试。

当我们运行代码,没有发生错误时,只会有一条提示测试开始运行的信息:

Testing started at 12:47 …

而发生错误时(例如把圆周率数值改为3.14),在PyCharm中我们能够看到测试失败的数量和一些具体的测试信息。

2、单元测试

对于大型的测试,我们可以使用unittest模块。

通过继承unittest模块定义测试类,并在类中定义不同的方法对功能代码进行测试。

假设我们有一个计算面积的area模块。

模块中包含两个函数,用于计算圆形面积和矩形面积。

示例代码:

def circular(r):  # 定义计算圆形面积的函数
    return round(3.14 * r * 2, 2)  # 注意:这个计算方法是错误的

def rectangle(w, h):  # 定义计算矩形面积的函数
    return w * h

然后,我们再创建一个用于测试的模块。

在测试模块中,我们就可以使用unittest模块编写测试组。

import unittest, area

class TestArea(unittest.TestCase):  # 定义测试类,继承unittest模块的TestCase类
    def test_circular(self):  # 定义测试圆形面积计算函数的方法
        rst = area.circular(2)  # 调用被测试的函数,传入参数,获取计算结果。
        self.assertEqual(rst, 3.14 * 4, '圆形的面积计算错误!')
        # 比较计算结果和预置的结果是否相等,如果不相等则测试失败,给出自定义提示。

    def test_rectangle(self):  # 定义测试矩形面积计算函数的方法
        rst = area.rectangle(3, 4)  # 调用被测试的函数,传入参数,获取计算结果。
        self.assertTrue(rst == 12, '矩形的面积计算错误!')
        # 通过表达式判断计算结果与预定的结果是否相等,如果表达式返回值为False,则测试失败,给出自定义提示。

if __name__ == '__main__':
    unittest.main() # 运行测试

上方代码中,我写出了两种对被测试函数计算结果和预置结果进行比较的方法:

  • assertEqual()方法能够比较第1个参数和第2个参数是否相等,如果不相等则会给出测试失败的结果,并显示第3个参数中自定义的提示。
  • assertTrue()方法的第1个参数是表达式,如果表达式的结果是False,则会给出测试失败的结果,并显示第2个参数中自定义的提示。

而且,上方代码中每一个测试方法都是以“test”开头,这是必须的。

因为,运行测试的语句“unittest.main() ”只会自动运行测试类中所有以“test”开头的方法。

不过,上方的代码运行后虽然没有给出测试失败的提示,但是,其实计算圆形面积函数的计算方法是错误的,只不过刚好我们给的参数(2)无法发现错误。

当我们把测试的参数改为3,就会提示测试失败,显示提示信息:

(…省略了部分提示…)

AssertionError: 18.84 != 28.26 : 圆形的面积计算错误!

(…省略了部分提示…)

所以,当我们编写测试程序的时候,一定要考虑全面,尽量模拟出所有可能导致程序出现问题的情形。

另外,还要注意,这里的示例只是演示了模块的基本使用方法,在实际编程中测试不会这么简单。

三、日志

日志一般是用来记录程序运行相关的数据,也能在程序出现问题时帮我们排查错误。

接下来,我们使用logging模块来完成记录程序运行日志的功能。

日志文件通过logging模块中的basicConfig()函数创建,函数的第一个参数是日志记录的级别,第二个参数是日志文件的名称。

示例代码:

import logging, time

log_time = time.strftime('%Y-%m-%d', time.localtime(time.time()))  # 获取当前日期
logging.basicConfig(level=logging.INFO, filename=log_time + '.log')  # 创建日志文件
logging.info('%s 程序开始...' % time.ctime())  # 写入日志记录
try:
    for i in range(-5, 5):
        logging.info('正在计算 12 /%d ...' % i)  # 写入日志记录
        print(12 / i)
except Exception as e:
    logging.info('发生错误:' + str(e))  # 写入日志记录
    raise
logging.info('%s 程序结束...' % time.ctime())  # 写入日志记录

在上方代码中,程序的功能是除法计算,但会有零除的错误产生。

通过日志,我们就能够得到程序每一次运算过程的记录以及出错时的异常信息。

运行代码之后,会生成当天的日志文件,并记录内容。

日志内容如下:

INFO:root:Thu Dec 7 13:30:09 2017 程序开始…
INFO:root:正在计算 12 /-5 …
INFO:root:正在计算 12 /-4 …
INFO:root:正在计算 12 /-3 …
INFO:root:正在计算 12 /-2 …
INFO:root:正在计算 12 /-1 …
INFO:root:正在计算 12 /0 …
INFO:root:发生错误:division by zero

本节知识点:

1、配置文件

2、文档测试和单元测试

3、程序日志

本节英文单词与中文释义:

1、config:配置

2、size:尺寸

3、color:颜色

4、background:背景

5、boder:边框

6、test:测试

7、driven:驱动

8、development:开发

9、perimeter:周长

10、mod(module):模块

11、param:参数

12、unittest:单元测试

13、area:面积

14、circular:圆形

15、rectangle:矩形

16、round:把…四舍五入

17、assert:断言

18、equal:相等

19、main:主要的

20、logging/log:记录/日志

21、basic:基本的

22、info:信息

23、strftime(string format time):字符串格式的时间

24、root:根本

25、division:除法

26、zero:零

转载请注明:魔力Python » Python3萌新入门笔记(53)

头像
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网站 (可选)