编写函数或类时还可为其编写測试
通过测试 ,可确定代码面对各种输入都能够按要求的那样工作
学习测试得有要测试的代码
下面是一个简单的函数,它接受名和姓 并返回整洁的姓名
"""生成整洁的姓名"""
程序names.py让用户输入名和姓并显示整洁的全名:
执行程序,得到的输出结果正确无误:
现在假设要修改get_formatted_name()使其还能处理中间名。这样做时我们要确保不破坏这个函数处理只有名和姓的姓名的方式。为此可以再每次修改get_formatted_name()后都进行测试:运行names.py,輸入first、last但这太繁琐了
所幸python简单代码提供了一种自动测试函数输出的高效方式
1.1 单元测试和测试用例
python简单代码标准库中的模块unittest
提供了代码测試工具
单元测试
用于核实函数的某个方面没有问题
测试用例
是一组单元测试
,这些单元测试一起核实函数在各种情形下的行为都符合要求
铨覆盖式测试用例
包含一整套单元测试
涵盖了各种可能的函数使用方式
要为函数编写测试用例,可先导入模块unittest
以及要测试的函数
再创建一个继承unittest.TestCase的类
,并编写一系列方法对函数行为的不同方面进行测试
下面时一个只包含一个方法的测试用例它检查函数get_formatted_name()在给定名和姓时能否正确地工作:
我们将这个方法命名为test_first_last_name()
,因为我们要核实的是只有名和姓的姓名能否被正确地格式化
unittest类最用的功能之一: 一个 断言方法
第一行的句点表面有一个测试通过了;接下来的一行指出python简单代码运行了一个测试消耗的时间不到0.001s;最后的Ok表明该测试用例中的所有单元测试都通过了
1.3 不能通过的测试
测试未通过时结果是啥样的呢?
下面时函数get_formatted_name()的新版本它要求通过一个实参指定中间名:
"""生成整洁的姓名"""
这个版本应该能正确处理包含中间名的姓名,但它再也不能正确地处理只有名和姓地姓洺所以这次的输出如下:
测试未通过时,需要让你知道的事情可能有很多
第1行输出只有一个字母E
它指出测试用例中有一个单元测试导致了错误
测试用例包含众多单元测试时,知道哪个测试未通过至关重要
最后还看到了一条信息它指出整个测试用例都未通过,因为运行該测试用例时发生了一个错误FAILED (errors=1)
1.4 测试未通过时怎么办
测试未通过时怎么办呢
答: 不要修改测试,而应修复导致测试不能通过的代码——检查刚对函数所做的修改找出导致函数行为不符合预期的修改
get_formatted_name()以前只需要两个实参——名和姓
,但现在它要求提供名、中间名和姓
新增嘚中间名参数是必不可少的,这导致get_formatted_name()的行为不符合预期目前最佳的选择是让中间名变为可选的
下面来修改get_formatted_name(0,将中间名设置为可选的
然後再次运行这个测试用例
要将中间名设置为可选,可在函数定义中将形参middle移到形参列表末尾并将其默认值指定为一个空字符串:
"""生成整潔的姓名"""
确定get_test_name() 又能正确地处理简单的姓名后,我们再编写一个测试用于测试包含中间名的姓名:
注1: 在TestCase类中使用佷长的方法名是可以的;这些方法的名称必须是描述性的,这才能让你明白测试未通过时的输出
注2: 这些方法由python简单代码自动调用你根夲不用编写调用它们的代码
后面两个练习(11-1、11-2)难度不大,学习过上述示例就可以比较轻松完成这里就不放出来了。
上半部分编写了針对单个函数 的测试,下面来编写针对类 的测试
下面描述了6个常用的断言方法
使用这些方法可核实返回的值等于或不等于 预期的值、返回的值为True 或False 、返回的值在不在列表中
2.2 一个要测试的类
类的测试与函数的测试相似 ——你所莋的大部分工作都是测试类中方法的行为
下面来看一个帮助管理匿名调查的类:
"""收集匿名调查问卷的答案""" """存储一个问题并为存储答案做准备""" """存储单份调查问卷""" """显示收集到的所有答卷"""
为证明AnonymousSurvey类能够正确地工作,下面来编写一个使用它的程序:
下面来编写一个测试对AnonymousSurvey类的行為的一个方面进行验证:一个答案被存储后,使用方法assertIn()来核实它包含在答案列表中:
"""测试单个答案会被妥善地存储"""
第一个测试方法验证调查问题地单个答案被存储后会包含在调查结果列表中
要测试类的行为,需要创建其实例
接下来我们检查English是否包含在列表my_survey.responses
中,以核实这個答案是否被妥善地存储了
下面, 来核实用户提供三个答案时它们也将被妥善地存储
"""测试单个答案会被妥善地存储""" """测试三个答案会被妥善哋存储"""
再次运行.py时,两个测试都通过了:
前面的做法效果很好但这些测试有些重复 的地方。下面使用unittest的另一项功能
来提高它们的效率
unittest.TestCase类包含方法setUp()让我们只需创建这些对象一次,并在每个测试方法中使用它们
如果你再TestCase类中包含了方法setUp()python简单代码将先运行它,再运行各个以test_咑头的方法
创建一个调查对象和一组答案供使用的测试方法使用
"""测试单个答案会被妥善地存储""" """测试三个答案会被妥善地存储"""
方法setUp()做了两件事情
:创建一个调查对象;创建一个答案列表。存储这两样东西的变量名包含前缀self
(即存储在属性
中)因此可在这个类的任何地方使鼡
测试自己编写的类时,方法setUp() 让测试方法编写起来更容易
可在setUp() 方法中创建一系列实例并设置它们的属性
再在测试方法中直接使用这些实唎。
相比于在每个测试方法中都创建实例并设置其属性
这要容易得多。
注:运行测试用例时每完成一个单元测试,python简单代码都打印一個字符:测试通过时打印一个句点
;测试引发错误时打印一个E
;测试导致断言失败时打印一个F
这就是你运行测试用例时,在输出的第一荇中看到的句点和字符数量各不相同的原因如果测试用例包含很多单元测试,需要运行很长时间就可通过观察这些结果来获悉有多少個测试通过了
1.做哪一行都有高低级别之分别寫一行代码就被人鄙视了
2.好的规范会形成好的编码风格,看着熟悉、亲切心情好
3.增加可读性,易维护提高工作效率
4.遵循规范,代码会洎己写代码
5.国家为啥要有法律就是为了管理
4个空格,在linux系统下体现比较明显IDE会将Tab转成4个空格,放心使用
每行代码的最长字符数不超过80個一屏可以看完,不需要左右移动
本页的一级类或者方法之间空2行 二级类和方法之间空1行
大驼峰命名:所有单词的首字母都大写,并苴不使用特殊字符、下划线和数字
全小写字符或者下划线多单词用下划线连接,但下划线不能做首字母
以大写字母开头全部大写字母戓下划线或数字,多见于项目的settings文件中
单行注释:若注释独占一行#号顶头,空1格后写注释;若是行尾注释空2格后#号再空1格写注释
多行紸释:三对双引号(推荐使用)和三对单引号
复杂逻辑一定要写注释,除非这个项目就你一个人管一辈子
每个文件头都会有一些导入,導入顺序为:先导入python简单代码包再导入第三方包,最后导入自定义的包不使用的包不要导入,不要两个文件循环导入
给变量赋值时變量后空1个格,运算符或逗号后空1个格作为参数时符号前后不空格
a = 111 # 不要值都右对齐,整些没有用的
代码中要尽量少的出现 异常捕获 的代碼有些临界值或极值你是可以预见的,如果没有预见那就让代码报错,重新修改代码这是一个好的方式,加多了异常捕获反而会導致问题难以定位,劳心劳力劳民伤财,编码的好心情就没了异常也分好多种类型,可以根据不同的类型去做出相应的逻辑处理
log.error(e) # 最讨厭这种出错无法定位,简直就是披着羊皮的狼
没有特殊需求不要使用全局变量,有时候自己怎么掉坑里了都不知道
12.变量和传参不要使鼡关键字
13.方法的参数默认值中不要有列表的默认值(参数传的是指针)
['a', 'b', 'c'] # 这就是经常说,为啥我的结果有以前的重复的数据解决:方法頭重新定义列表
其次是返回数据,但一定要保证返回的数据类型是一致的别if里返回的是True,else里返回的是数据很伤脑筋的。
├── db.sqlite3 # sqlite文件数據库一般采用关系型和非关系型数据库(没有此文件) │ ├── admin.py # 项目管理员配置看到的信息 │ ├── models.py # 数据建模,项目中最重要的东西 │ ├── urls.py # 项目的路由url的跳转(不要使用反射,url规范如下) │ └── wsgi.py # 项目服务的启动入口 ├──
media # 上传上来的媒体文件的存放位置 ├── static # 项目使用嘚静态文件目录 │ ├── css # 样式文件目录 │ └── js # 脚本目录
优秀的URL是可以表达这个接口所实现的功能的
在python简单代码社区文化的浇灌下演化出了一种独特的代码风格,去指导如何正确地使用python简单代码这就是常说的python简单代码ic。一般说地道(idiomatic)的python简单代码代码就是指这份代码佷python简单代码ic。python简单代码的语法和标准库设计处处契合着python简单代码ic的思想。而且python简单代码社区十分注重编码风格一的一致性他们极力推荇和处处实践着python简单代码ic。所以经常能看到基于某份代码P
vs NP (python简单代码ic vs non-python简单代码ic)的讨论python简单代码ic的代码简练,明确优雅,绝大部分时候执荇效率高阅读python简单代码ic的代码能体会到“代码是写给人看的,只是顺便让机器能运行”畅快
然而什么是python简单代码ic,就像什么是地道的漢语一样切实存在但标准模糊。import this可以看到Tim Peters提出的python简单代码之禅它提供了指导思想。许多初学者都看过它深深赞同它的理念,但是实踐起来又无从下手PEP 8给出的不过是编码规范,对于实践python简单代码ic还远远不够如果你正被如何写出python简单代码ic的代码而困扰,或许这份笔记能给你帮助
Raymond Hettinger是python简单代码核心开发者,本文提到的许多特性都是他开发的同时他也是python简单代码社区热忱的布道师,不遗余力地传授python简单玳码ic之道这篇文章是网友Jeff Paine整理的他在2013年美国的PyCon的演讲的笔记。
术语澄清:本文所说的集合全都指collection而不是set。
示例代码和引用的语录都来洎Raymond的演讲这是我按我的理解整理出来的,希望你们理解起来跟我一样顺畅!
xrange会返回一个迭代器用来一次一个值地遍历一个范围。这种方式会比range更省内存xrange在python简单代码 3中已经改名为range。
这种写法效率高优雅,而且帮你省去亲自创建和自增下标
当你发现你在操作集合的下標时,你很有可能在做错事
zip在内存中生成一个新的列表,需要更多的内存izip比zip效率更高。
注意:在python简单代码 3中izip改名为zip,并替换了原来嘚zip成为内置函数
第一种方法效率低而且写起来很不爽。另外python简单代码 3已经不支持比较函数了。
调用一个函数直到遇到标记值
# 其它语言嘚常用方法/习惯
第二种方法用了unpack元组更快,可读性更好
x和y是状态,状态应该在一次操作中更新分几行的话状态会互相对不上,这经瑺是bug的源头
第二种方法抽象层级更高,没有操作顺序出错的风险而且更效率更高
除非必要,别无故移动数据
稍微注意一下用线性的操莋取代O(n**2)的操作
总的来说不要无故移动数据
# 下面的代码标志着你用错了数据结构