一、Python介绍
- Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。
Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构。 - Python 是一种解释型语言: 这意味着开发过程中没有了编译这个环节。类似于PHP和Perl语言。
- Python 是交互式语言: 这意味着,您可以在一个Python提示符,直接互动执行写你的程序。
- Python 是面向对象语言: 这意味着Python支持面向对象的风格或代码封装在对象的编程技术。
- Python 是初学者的语言:Python 对初级程序员而言,是一种伟大的语言,它支持广泛的应用程序开发,从简单的文字处理到 WWW 浏览器再到游戏。
二、发展历程
- Python 是由 Guido van Rossum 在八十年代末和九十年代初,在荷兰国家数学和计算机科学研究所设计出来的。
- Python 本身也是由诸多其他语言发展而来的,这包括 ABC、Modula-3、C、C++、Algol-68、SmallTalk、Unix shell 和其他的脚本语言等等。
- 像 Perl 语言一样,Python 源代码同样遵循 GPL(GNU General Public License)协议。
- 现在 Python 是由一个核心开发团队在维护,Guido van Rossum 仍然占据着至关重要的作用。
三、Python的特点
- 易于学习:Python有相对较少的关键字,结构简单,和一个明确定义的语法,学习起来更加简单。
- 易于阅读:Python代码定义的更清晰。
- 易于维护:Python的成功在于它的源代码是相当容易维护的。
- 一个广泛的标准库:Python的最大的优势之一是丰富的库,跨平台的,在UNIX,Windows和Macintosh兼容很好。
- 互动模式:互动模式的支持,您可以从终端输入执行代码并获得结果的语言,互动的测试和调试代码片断。
- 可移植:基于其开放源代码的特性,Python已经被移植(也就是使其工作)到许多平台。
- 可扩展:如果你需要一段运行很快的关键代码,或者是想要编写一些不愿开放的算法,你可以使用C或C++完成那部分程序,然后从你的Python程序中调用。
- 数据库:Python提供所有主要的商业数据库的接口。
- GUI编程:Python支持GUI可以创建和移植到许多系统调用。
- 可嵌入: 你可以将Python嵌入到C/C++程序,让你的程序的用户获得"脚本化"
四、Pycharm及python安装详细教程
4.1. 安装python
4.1.1. python下载地址
进入之后如下图,选择图中红色圈中区域进行下载
image.png
4.1.2. 下载完成后如下图所示
image.png4.1.3. 安装
双击exe文件进行安装,如下图,并按照圈中区域进行设置,切记要勾选打钩的框,然后再点击Customize installation进入到下一步:
image.png
image.png
image.png
4.1.4. 自定义安装路径
对于上图中,可以通过Browse进行自定义安装路径,也可以直接点击Install进行安装,点击install后便可以完成安装了。
image.png
4.1.5. 检测安装是否成功
为了检查我们的python是否安装成功,可以在命令窗口中输入python进行查询,如显示下图一的信息则表示成功了,如显示第二张图的信息则表示出错了。
image.png
4.2. 安装pycharm
4.2.1. 下载地址
首先从网站下载pycharm,进入之后如下图,根据自己电脑的操作系统进行选择,对于windows系统选择图中红色圈中的区域。
image.png
4.2.2. 下载完成之后如下图:
image.png4.2.3. 直接双击下载好的exe文件进行安装,安装截图如下:
image.png点击Next进入下一步:
image.png
点击Next进入下一步:
image.png
点击Install进行安装:
image.png
image.png
安装完成后出现下图界面,点级Finish结束安装:
image.png
下面我们来创建自己的第一个程序:
1、单击桌面上的pycharm图标,进入到pycharm中,如下图所示:
image.png
2、我们选择第二个,然后点击Ok:
image.png
3、点击上图中的Accept进入下一步:
image.png
4、点击上图中的ok进入下一步:
image.png
5、点击Create New Project,进入如下图的界面,图中的Location是选择你安装的python的位置,选择好后,点击create。
image.png
五、第一个Python程序
1.创建python file
2.练习打印hello world
image.png六、Python变量和数据类型
6.1. 变量的定义
在程序中,有时我们需要对2个数据进行求和,那么该怎样做呢?
大家类比一下现实生活中,比如去超市买东西,往往咱们需要一个菜篮子,用来进行存储物品,等到所有的物品都购买完成后,在收银台进行结账即可
如果在程序中,需要把2个数据,或者多个数据进行求和的话,那么就需要把这些数据先存储起来,然后把它们累加起来即可
在Python中,存储一个数据,需要一个叫做变量的东西,如下示例:
num1 = 100 #num1就是一个变量,就好一个小菜篮子
num2 = 87 #num2也是一个变量
result = num1 + num2 #把num1和num2这两个"菜篮子"中的数据进行累加,然后放到 result变量中
说明:
- 所谓变量,可以理解为菜篮子,如果需要存储多个数据,最简单的方式是有多个变量,当然了也可以使用一个
- 程序就是用来处理数据的,而变量就是用来存储数据的
程序中:
为了更充分的利用内存空间以及更有效率的管理内存,变量是有不同的类型的,如下所示:
Python3 中有六个标准的数据类型:
image.png
Python3 的六个标准数据类型中:
- 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
- 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。
注意:在python中,只要定义了一个变量,而且它有数据,那么它的类型就已经确定了,不需要咱们开发者主动的去说明它的类型,系统会自动辨别
可以使用type(变量的名字),来查看变量的类型
6.1.1 概念
- 整数
Python可以处理任意大小的整数,当然包括负整数,在Python程序中,整数的表示方法和数学上的写法一模一样,例如:1,100,-8080,0,等等。 - 浮点数
浮点数也就是小数,之所以称为浮点数,是因为按照科学记数法表示时,一个浮点数的小数点位置是可变的,比如,1.23x109和12.3x108是相等的。浮点数可以用数学写法,如1.23,3.14,-9.01,等等。
整数和浮点数在计算机内部存储的方式是不同的,整数运算永远是精确的(除法难道也是精确的?是的!),而浮点数运算则可能会有四舍五入的误差。 - 字符串
字符串是以''或""括起来的任意文本,比如'abc',"xyz"等等。请注意,''或""本身只是一种表示方式,不是字符串的一部分,因此,字符串'abc'只有a,b,c这3个字符。 - 布尔值
布尔值和布尔代数的表示完全一致,一个布尔值只有True、False两种值,要么是True,要么是False,在Python中,可以直接用True、False表示布尔值(请注意大小写),也可以通过布尔运算计算出来。
布尔值可以用and、or和not运算。
and运算是与运算,只有所有都为 True,and运算结果才是 True。A与B true true
or运算是或运算,只要其中有一个为 True,or 运算结果就是 True。
not运算是非运算,它是一个单目运算符,把 True 变成 False,False 变成 True。 - 空值
空值是Python里一个特殊的值,用None表示。None不能理解为0,因为0是有意义的,而None是一个特殊的空值。
6.1.2 代码示例
#整数
a=1;
#浮点数
b=1.1;
#字符串
c="abc";
#boolean类型
d=True;
#空值
e=None;
print(a);print(b);print(c);print(d);print(e)
a=True and True # ==> True
b=True and False # ==> False
c=False and True # ==> False
d=False and False # ==> False
e=True or True # ==> True
f=True or False # ==> True
g=False or True # ==> True
h=False or False # ==> False
i=not True # ==> False
j=not False # ==> True
print(a,b,c,d,e,f,g,h,i,j)
说明:
- 在计算 a and b 时,如果 a 是 False,则根据与运算法则,整个结果必定为 False,因此返回 a;如果 a 是 True,则整个计算结果必定取决与 b,因此返回 b。
- 在计算 a or b 时,如果 a 是 True,则根据或运算法则,整个计算结果必定为 True,因此返回 a;如果 a 是 False,则整个计算结果必定取决于 b,因此返回 b。
所以Python解释器在做布尔运算时,只要能提前确定计算结果,它就不会往后算了,直接返回结果。
6.1.3 标识符
- 什么是标识符?
开发人员在程序中自定义的一些符号和名称
标识符是自己定义的,如变量名 、函数名等 - 标识符的命名规则
. 标识符只能由字母、下划线“_”、数字组成。
. 标识符不能以数字开头。
. 标识符不能使用关键字
. 标识符对大小写敏感。
(建议:标识符命名应“见名知意”)
- python中的关键字
'False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
- 注释:
- 单行注释:
/* */
//定义一个变量
name="jack"
- 多行注释:
'''
定义一个变量
'''
name="jack"
- 课堂思考:下列哪些标识符符合规则
if name and my_list my_list1 from#1 age 2list as True wetyui
height my_log qwe&qwe
- 标识符的命名方法
- 小驼峰式命名法:
函数名 addName
- 大驼峰式命名法:
类名 AddName
6.2.Python中print语句
print() 方法用于打印输出,最常见的一个函数。
语法:
print(*objects, sep=' ', end='\n', file=sys.stdout)
参数:
objects -- 复数,表示可以一次输出多个对象。输出多个对象时,需要用 , 分隔。
sep -- 用来间隔多个对象,默认值是一个空格。
end -- 用来设定以什么结尾。默认值是换行符 \n,我们可以换成其他字符串。
file -- 要写入的文件对象。
#直接打印
print("哈哈哈哈")
#多条打印
print("哈哈哈哈","呵呵呵呵","吼吼吼吼"),
#打印+计算
print("100+200的和是:",100+200);
#设置间隔符号
print("www","runoob","com",sep=".") # 设置间隔符 www.runoob.com
格式化输出
方式一:使用百分号(%)字符串格式化
print("my name is %s, and my age is %d" %(name,age))
方式二:使用format字符串格式化
位置参数
print("my name is {}, and my age is {}".format(age,name))
关键字参数
print("my name is {name}, and my age is {age}".format(age=18,name="jack"))
注释:位置参数("{0}".format()),关键字参数("{关键字}".format())
6.3.设置换行符号
print(a,b,c,d,e,sep=";",end="\n");
6.4.Python中input语句
input() 用来获取控制台的输入。
语法:
input([prompt])
image.png
6.5.Python中变量
- 在Python中,变量的概念基本上和初中代数的方程变量是一致的。
例如,对于方程式 y=x*x ,x就是变量。当x=2时,计算结果是4,当x=5时,计算结果是25。 - 只是在计算机程序中,变量不仅可以是数字,还可以是任意数据类型。
在Python程序中,变量是用一个变量名表示,变量名必须是大小写英文、数字和下划线(_)的组合,且不能用数字开头,比如:
a = 123 # a是整数
print (a)
a = 'imooc' # a变为字符串
print (a)
b=11; #b是整数
d=11.1;#d是浮点数
print(b*d)
七、Python条件循环和判断
7.1. If语句
Python 编程中 if 语句用于控制程序的执行,基本形式为:
if 判断条件:
执行语句……
else:
执行语句……
其中"判断条件"成立时(非零),则执行后面的语句,而执行内容可以多行,以缩进来区分表示同一范围。
else 为可选语句,当需要在条件不成立时执行内容则可以执行相关语句,具体
7.2.If else 语句
age = 12
if age>18:
print("年龄大于18")
else:
print("年龄小于等于18")
age=20;
if age>18:
print("年龄大于18")
if not age <=18:
print("年龄大于18")
注意:Python代码的缩进规则。具有相同缩进的代码被视为代码块,上面的 print 语句就构成一个代码块。如果 if 语句判断为 True,就会执行这个代码块。
缩进请严格按照Python的习惯写法:4个空格,一个Tab,更不要混合Tab和空格,否则很容易造成因为缩进引起的语法错误。
7.3. If else else 多层嵌套方式
age=10;
if age >= 18:
print ('adult')
else:
if age >= 6:
print ('teenager')
else:
if age >= 3:
print ('kid')
else:
print ('baby')
标准格式
if 语句的判断条件可以用>(大于)、<(小于)、==(等于)、>=(大于等于)、<=(小于等于)来表示其关系。
当判断条件为多个值时,可以使用以下形式:
if 判断条件1:
执行语句1……
elif 判断条件2:
执行语句2……
elif 判断条件3:
执行语句3……
else:
执行语句4……
案例:
score=85;
if score>=90:
print("成绩优秀")
elif score>=80:
print("成绩不错")
elif score>=60:
print("及格")
else:
print("不及格");
7.4. For循环:重复执行语句
for n in range(1, 20):
print(n)
arr = [100, 90, 86, 80, 77]
for index in arr:
print(index)
注意: b这个变量是在 for 循环中定义的,意思是,依次取出list中的每一个元素,并把元素赋值给 name,然后执行for循环体(就是缩进的代码块)
练习:求四个同学的平均成绩 L = [75, 92, 59, 68]
arr = [100, 90, 86, 80, 77]
sum = 0.0
for index in arr:
sum += index
print(sum/len(arr))
7.5. While 循环
Python 编程中 while 语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务。其基本形式为:
while 判断条件:
执行语句……
执行语句可以是单个语句或语句块。判断条件可以是任何表达式,任何非零、或非空(null)的值均为true。当判断条件假false时,循环结束,while 循环不会迭代 list 或 tuple 的元素
要从 0 开始打印不大于 N 的整数:
N = 20
i = 0
while i < N:
print(i)
i += 1;
练习:求100以内的和
sum = 0
i = 0
while i < 100:
sum += i
i += 1
print(sum)
7.6. Break中断循环
break语句用来终止循环语句,即循环条件没有False条件或者序列还没被完全递归完,也会停止执行循环语句。
break语句用在while和for循环中。
如果您使用嵌套循环,break语句将停止执行最深层的循环,并开始执行下一行代码。
var = 10
while var > 0:
print(var)
var = var - 1
if var == 5: # 当变量 var 等于 5 时退出循环
break
7.7. Continue
Python continue 语句跳出本次循环,而break跳出整个循环。
continue 语句用来告诉Python跳过当前循环的剩余语句,然后继续进行下一轮循环。
continue语句用在while和for循环中。
var = 10
while var > 0:
var = var -1
if var == 5:
continue
print(var)
7.8.嵌套循环
Python 语言允许在一个循环体里面嵌入另一个循环
for x in ['A', 'B', 'C']:
for y in ['1', '2', '3']:
print (x + y)
7.9.Python字符串操作
- 字符串转义
a='learn "python" from teacher liang';
b='bob said \"I\'m ok\"';
print(a)
print(b);
\n 表示换行
\t 表示一个制表符
\ 表示 \ 字符本身
- 字符串截取操作(左闭右开)
a="hello world";
print(a[0:2]) #he 截取字符串 从第0到第2个 包含头不包含尾
print(a[1]) #e 某个索引的字符
- 字符串拼接
b="hello";
c="world"
d=b+c;
print(d)#hello world 字符串拼接
- 包含不包含,使用
in
和not in
判断是否包含
e="hello world";
f='he' in e;
g='haahha' in e;
h="he" not in e;
i='haahha' not in e;
print(f,g); #True False 判断是否包含
print(h,i); #False true 判断是否不包含
- 常用字符串的操作api
a="hello world"
print(a.upper())#HELLO WORLD 变成大写
b=a.startswith("hello");#true 是以什么进行开头
c=a.endswith("world");#true 以什么进行结尾
d=a.replace("h","hhhhh");#hhhhhello world 替换字符
print(d);
八、Python中List和Tuple类型
序列是Python中最基本的数据结构。
序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推。
Python有6个序列的内置类型,但最常见的是列表和元组。
序列都可以进行的操作包括索引,切片,加,乘,检查成员。
此外,Python已经内置确定序列的长度以及确定最大和最小的元素的方法。
列表是最常用的Python数据类型,它可以作为一个方括号内的逗号分隔值出现。
列表的数据项不需要具有相同的类型
创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可。如下所示:
a= ['physics', 'chemistry', 1997, 2000]
b = [1, 2, 3, 4, 5 ]
c = ["a", "b", "c", "d"]
8.1. 定义集合
a=["aaa",123,"bbb",True];#定义集合
8.2. 获取某个索引的元素
print(a[1]);#123 获取索引值为1处的元素
8.3. 倒序获取元素
print(a[-1],a[-2],a[-3],a[-4]);#True bbb 123 aaa 倒数第一个,倒数第二个,倒数第三个
8.4.添加元素
- 追加
a.append("哈哈哈");
print(a);#['aaa', 123, 'bbb', True, '哈哈哈']
- 插入
a.insert(1,"82岁韩美林);
a.insert(2,"PGone")
print(a);#['aaa', '李小璐', 'PGone', 123, 'bbb', True, '哈哈哈']
8.5.删除元素
a.pop(2);
a.pop(1);
print(a);#['aaa', 123, 'bbb', True, '哈哈哈'] 删除某索引值的元素
8.6.替换元素
a[2]="贾乃亮";
a[-1]="吼吼吼"
print(a);#['aaa', 123, '贾乃亮', True, '吼吼吼'] 替换指定位置元素
8.7.定义元组(Tuple)[ˈtjup(ə)l]
Python的元组与列表类似,不同之处在于元组的元素不能修改。
元组使用小括号,列表使用方括号。
元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。
t = ('Adam', 'Lisa', 'Bart')
现在,这个 t 就不能改变了,tuple没有 append()方法,也没有insert()和pop()方法。所以,新同学没法直接往 tuple 中添加,老同学想退出 tuple 也不行。
a=("a","b","c");
print(a);#('a', 'b', 'c')
8.8. 可变Tuple
元组可以使用下标索引来访问元组中的值,如下实例:
a = (1, 2, 3, 4, 5, 6, 7 )
print(a[1:5]) # 2,3,4,5
元组中的元素值是不允许修改的,但我们可以对元组进行连接组合,如下实例:
tup1 = (12, 34.56)
tup2 = ('abc', 'xyz')
tup3 = tup1 + tup2
print(tup3)
a=("a","b",["c"]);
print(a);#('a', 'b', 'c')
l=a[2];
l.insert(0,"d");
print(a)#('a', 'b', ['d', 'c'])
九、Dict介绍--字典类型 dictionary
9.1.字典介绍
我们已经知道,list 和 tuple 可以用来表示顺序集合,例如,班里同学的名字:
['Adam', 'Lisa', 'Bart']
或者考试的成绩列表:
[95, 85, 59]
但是,要根据名字找到对应的成绩,用两个 list 表示就不方便。
如果把名字和分数关联起来,组成类似的查找表:
'Adam' ==> 95
'Lisa' ==> 85
'Bart' ==> 59
给定一个名字,就可以直接查到分数。
Python的 dict 就是专门干这件事的。用 dict 表示“名字”-“成绩”的查找表如下:
d = {
'Adam': 95,
'Lisa': 85,
'Bart': 59
}
我们把名字称为key,对应的成绩称为value,dict就是通过 key 来查找 value。
花括号 {} 表示这是一个dict,然后按照 key: value, 写出来即可。最后一个 key: value 的逗号可以省略。
字典是另一种可变容器模型,且可存储任意类型对象。
字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中 ,格式如下所示:
d = {key1 : value1, key2 : value2 }
键必须是唯一的,但值则不必。
值可以取任何数据类型,但键必须是不可变的,如字符串,数字或元组。
一个简单的字典实例:
key value(键值对)形式数据对应,比如 name:张三 age:18 sex:男
info={"name":"张三","age":18,"sex":"男"}
9.2. Dict特点
- 字典和列表一样,也能够存储多个数据
- 列表中找某个元素时,是根据下标进行的;字典中找某个元素时,是根据'名字'(就是冒号:前面的那个值,例如上面代码中的'name'、'age'、'sex')
- dict的第一个特点是查找速度快,无论dict有10个元素还是10万个元素,查找速度都一样。而list的查找速度随着元素增加而逐渐下降。
- 不过dict的查找速度快不是没有代价的,dict的缺点是占用内存大,还会浪费很多内容,list正好相反,占用内存小,但是查找速度慢。
- 由于dict是按 key 查找,所以,在一个dict中,key不能重复。
- dict的第二个特点就是存储的key-value序对是没有顺序的!这和list不一样:
- dict的第三个特点是作为 key 的元素必须不可变,Python的基本类型如字符串、整数、浮点数都是不可变的,都可以作为 key。但是list是可变的,就不能作为 key。
9.3. 元素获取
print(info["name"])
print(info.get("name")) #
#print(info.get("xx")) 如果元素没有会报错误
9.4. 字典的增删改操作
- 修改元素
字典中每个元素都是可修改的,只要通过key找到,既可以修改Demoinfo["name"]="李四"
- 添加元素
想要添加元素,只需要指定key 指定 value就可以info["address"]="北京"
- 删除元素
对字典进行删除操作,有以下两种方式:# del info[] 指定要删除的元素 del info["name"] # clear 清空元素 info.clear()
9.5. 字典内置函数&方法
号 | 函数及描述 | 实例 |
---|---|---|
1 | len(dict) | 计算字典元素个数,即键的总数。 >>> dict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}>>> len(dict)3 |
2 | str(dict) | 输出字典,以可打印的字符串表示。 >>> dict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}>>> str(dict)"{'Name': 'Runoob', 'Class': 'First', 'Age': 7}" |
3 | type(variable) | 返回输入的变量类型,如果变量是字典就返回字典类型。 >>> dict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}>>> type(dict)<class 'dict'> |
9.6.字典的常见操作
- keys() 获取字典的所有key 列表
print(info.keys())
- values 获取字典的所有values 列表
print(info.values())
- items 返回一个包含所有元组(键,值)的列表
print(info.items())
9.7. 字典的遍历
- 遍历key
for key in info.keys(): print(key)
- 遍历value
for value in info.values(): print(value)
- 遍历items
for item in info.items(): print(item)
- 遍历key value
for key,value in info.items(): print(key,value)
十、Python中函数
10.1.什么是函数
如果在开发的时候,需要某块代码多次,但是为了提高便携的效率以及代码的重用,所以把具有独立功能的代码块组织成一个小的模块,这就是函数。
10.2.函数定义和调用
10.2.1. 定义函数
- 定义函数的格式如下:
def 函数名(): 代码
- 定义一个函数,能够完成打印信息的功能
def printInfo(): print '------------------------------------' print ' 人生苦短,我用Python' print '------------------------------------'
10.2.2. 调用函数
定义了函数之后,就相当于有了一个具有某些功能的代码,想要让这些代码能够执行,需要调用它
调用函数很简单的,通过函数名() 即可完成调用
- 案例:
# 定义完函数后,函数是不会自动执行的,需要调用它才可以 printInfo()
10.3.函数的好处
减少代码的冗余,减少维护量,功能的封装,降低学习成本,提高开发速度
10.4. 函数参数
- 定义带有参数的函数:
def printSum(a,b): print(a+b)
- 调用带有参数的函数
printSum(10,20)
形式参数和实际参数
定义时小括号中的参数,用来接受参数用的,称为“形参”
调用时小括号中的参数,用来传递给函数用的,称为”实际参数”
10.5.缺省参数
默认有参数值的函数
def student(name,age,sex="男"):
print(name,age,sex)
student("格日仓",18)
student("格日仓",20,"女")
10.6. 可变参数(一 元组类型)
def getSum(*args):
print(args)
sum=0
for i in args:
sum+=i
return sum
print(getSum(1,2,3,4))
10.7. 可变参数(二 字典类型)
dic = {
'a': 90,
'b': 80,
'c': 70,
'd': 100
}
def kv(**kwargs):
print(kwargs)
kv(a=90,b=80,c=70,d=100)
十一、函数返回值
所谓返回值,就是程序中函数完成一件事后,最后给调用者的结果。
11.1.定义带有返回值的函数
11.2.调用带有返回值参数的函数
11.3.多个返回值的函数
案例:两个数字除数和商
十二、函数类型
12.1.无参数,无返回值的函数
12.2.无参数,有返回值的函数
12.3.有参数,无返回值的函数
12.4.有参数,有返回值的函数
十三、函数的嵌套调用
案例:在函数A中调用函数B,然后调用函数。
分析调用顺序。
def add ():
print("这是add1")
print("加法运算的逻辑")
def add2():
print("想实现加法的运算")
add()
print("计算出一个结果")
add2()
十四、局部变量
局部变量,就是在函数内部定义的变量
不同的函数,可以定义相同的名字的局部变量,各用个的不会影响
局部变量作用:为了临时保存数据需要在函数中定义变量来存储。
十五、全局变量
如果一个变量,既能在一个函数中使用,又能在其他函数中使用,这样的变量就是全局变量。
在函数外边定义的变量叫做全局变量
全局变量能够在所有的函数中进行访问
如果在函数中修改全局变量,那么就需要使用global进行声明,否则出错
如果全局变量的名字和局部变量的名字相同,那么使用的是局部变量的
#全局变量,局部变量
#全局变量:在函数外定义的变量
#局部变量:在函数内部定义的变量
#全局变量与局部变量,就近原则
a = 100
b = 200
def add():
global a #修改全局变量
a = 200 #局部变量
return a + b
def add2():
return a + b
re = add()
print(re)
print(add2())
十六、递归函数
如果一个函数在内部不调用其它的函数,而是自己本身的话,这个函数就是递归函数。
16.1.循环完成
求n的阶乘
def getMultipy(n):
i=1
result=1
while i<=n:
result=result*i
i+=1
return result
print(getMultipy(10))
16.2.函数调用函数自身
求n的阶乘
def getMultipy(n):
if n>=1:
result=n*getMultipy(n-1)
else:
result=1
return result
print(getMultipy(3))
十七、Python中模块和包
在Python中有一个概念叫做模块(module),这个和C语言中的头文件以及Java中的包很类似,比如在Python中要调用sqrt函数,必须用import关键字引入math这个模块。
- 导入模块import 语句
模块定义好后,我们可以使用 import 语句来引入模块,语法如下:
比如要引用模块 math,就可以在文件最开始的地方用 import math 来引入。import module1[, module2[,... moduleN]
在调用 math 模块中的函数时,必须这样引用:#模块名.函数名 import math print(math.pi);#3.141592653589793
- from…import 语句
Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中。语法如下:
from modname import name1[, name2[, ... nameN]]
例如,要导入模块 math 的 pi 函数,使用如下语句:from math import pi print(pi)
17.1.导入自定义模块
在test1中定义求和方法
def sum(a,b):
return a+b
test中直接导入方法
from test2 import sum
print(sum(1,2))
十八、文件操作
18.1. 什么是文件
使用文件的目的:就是把一些文件存储存放起来,可以让程序下一次执行的时候直接使用,而不必重新制作一份,省时省力
在操作文件的整体过程与使用word编写一份简历的过程是很相似的:
- 打开文件,或者新建立一个文件
- 读/写数据
- 关闭文件
18.2. 打开、关闭文件
python中打开文件,可以使用open函数,可以打开一个已经存在的文件,或者创建一个新的文件。
open(文件名,访问模式)
# 新建一个文件,文件名为:test.txt
f = open('test.txt', 'w')
# 关闭这个文件
f.close()
18.3. 文件访问模式
文件打开分为两种:文本模式(r/w/a),二进制模式(rb/wb/ab)
image.png
18.4. 文件的读写
-
写数据(write) - write()方法
write()方法可将任何字符串写入一个打开的文件。需要重点注意的是,Python字符串可以是二进制数据,而不是仅仅是文字。
write()方法不会在字符串的结尾添加换行符('\n'):f = open('test.txt', 'w') f.write('hello world, i am here!') f.close()
-
读数据(read)
使用read(num)可以从文件中读取数据,num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据f = open('test3.txt','r') print(f.read())
-
Python写入内容
file=open("test.txt","r+") content=file.read(2) print(content) content=file.read() print(content) file.close()
-
如果open是打开一个文件,那么可以不用写打开的模式,即只写 open('test.txt')
如果使用读了多次,那么后面读取的数据是从上次读完后的位置开始的
读数据(readline)按照行读取内容
Python写入内容file=open("test.txt","r+") content=file.readline() print(content) content=file.readline() print(content)
-
读数据(readlines)读取每一行
就像read没有参数时一样,readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素
#coding=utf-8
f = open('test.txt', 'r')
content = f.readlines()
print(type(content))
i=1
for temp in content:
print("%d:%s"%(i, temp))
i+=1
f.close()
file = open("E:\\ceshi.txt")
read = file.readlines()
read2= file.readline()
print(read)
print(read2)
18.5. File对象的属性
一个文件被打开后,你有一个file对象,你可以得到有关该文件的各种信息。
以下是和file对象相关的所有属性的列表:
属性 | 描述 |
---|---|
file.closed | 返回true如果文件已被关闭,否则返回false。 |
file.mode | 返回被打开文件的访问模式。 |
file.name | 返回文件的名称。 |
file.softspace | 如果用print输出后,必须跟一个空格符,则返回false。否则返回true。 |
如下实例:
#!/usr/bin/python# -*- coding: UTF-8 -*-
# 打开一个文件
fo = open("foo.txt", "w")
print "文件名: ", fo.name
print "是否已关闭 : ", fo.closed
print "访问模式 : ", fo.mode
print "末尾是否强制加空格 : ", fo.softspace
十九、文件的重命名、删除
有些时候,需要对文件进行重命名、删除等一些操作,python的os模块中都有这么功能
19.1.文件重命名
os模块中的rename()可以完成对文件的重命名操作
rename(需要修改的文件名, 新的文件名)
import os
os.rename("毕业论文.txt", "毕业论文-最终版.txt")
19.2.删除文件
os模块中的remove()可以完成对文件的删除操作
remove(待删除的文件名)
import os
os.remove("毕业论文.txt")
19.3.创建文件夹,删除文件夹
Python里的目录:
所有文件都包含在各个不同的目录下,不过Python也能轻松处理。
os模块有许多方法能帮你创建,删除和更改目录。
- mkdir()方法
可以使用os模块的mkdir()方法在当前目录下创建新的目录们。你需要提供一个包含了要创建的目录名称的参数。 - rmdir()方法
rmdir()方法删除目录,目录名称以参数传递。
注意:在删除这个目录之前,它的所有内容应该先被清除。
Import os
os.mkdir("aaa")
os.rmdir("test")
print(os.getcwd()) 获取当前目录
二十、文件拷贝
- 打开现有一个文件1,读取文件当中的内容
test = open("E:\\ceshi.txt","r")
read = test.readlines()
- 新建一个文件,写入文件1当中的内容
test2 = open("test2.txt","w")
for x in read:
test2.write(x)
test.close()
test2.close()
- 读取新文件内容
test3 = open("test2.txt",'r')
print(test3 .read())
十三、Python面向对象编程
面向过程:根据业务逻辑从上到下写代码
面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程
面向对象编程的2个非常重要的概念:类和对象
对象是面向对象编程的核心,在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,提出了另外一个新的概念——类
类就相当于制造飞机时的图纸,用它来进行创建的飞机就相当于对象
类与对象的关系:类就是创建对象的模板
13.1. Python定义类并创建实例
13.1.1 类(Class) 由3个部分构成:
类的名称:类名
类的属性:一组数据
类的方法:允许对进行操作的方法 (行为)
对象 = 属性 + 方法
静态 + 动态
引入:
-
案例一:人类设计,只关心3样东西:
事物名称(类名):人(Person)
属性:身高(height)、年龄(age)
方法(行为/功能):跑(run)、打架(fight) -
案例二:狗类的设计
类名:狗(Dog)
属性:品种 、毛色、性别、名字、 腿儿的数量
方法(行为/功能):叫 、跑、咬人、吃、摇尾巴
13.1.2 以 Person 为例,定义一个Person类如下:
class Person(object):
pass
xiaoming=Person();
xiaohong=Person();
print(xiaoming)#<__main__.Person object at 0x000001C113239128>
print(xiaohong)#<__main__.Person object at 0x000001C113239160>
print(xiaohong==xiaohong)#False
按照 Python 的编程习惯,类名以大写字母开头,紧接着是(object),表示该类是从哪个类继承下来的。类的继承将在后面的章节讲解,现在我们只需要简单地从object类继承。
pass语句什么也不做,一般作为占位符或者创建占位程序,pass语句不会执行任何操作
13.2.创建对象
通过上一节课程,定义了一个Car类;就好比有车一个张图纸,那么接下来就应该把图纸交给生成工人们去生成了
python中,可以根据已经定义的类去创建出一个个对象
创建对象的格式为:
对象名 = 类名()
创建对象demo:
# 定义类
class Car:
# 移动
def move(self):
print('车在奔跑...')
# 鸣笛
def toot(self):
print("车在鸣笛...嘟嘟..")
# 创建一个对象,并用变量BMW来保存它的引用
BMW = Car()
BMW.color = '黑色'
BMW.wheelNum = 4 #轮子数量
BMW.move()
BMW.toot()
print(BMW.color)
print(BMW.wheelNum)
image.png
总结:
- BMW = Car(),这样就产生了一个Car的实例对象,此时也可以通过实例对象BMW来访问属性或者方法
- 第一次使用BMW.color = '黑色'表示给BMW这个对象添加属性,如果后面再次出现BMW.color = xxx表示对属性进行修改
- BMW是一个对象,它拥有属性(数据)和方法(函数)
- 当创建一个对象时,就是用一个模子,来制造一个实物
13.3. Python中创建实例属性
虽然可以通过Person类创建出xiaoming、xiaohong等实例,但是这些实例看上除了地址不同外,没有什么其他不同。在现实世界中,区分xiaoming、xiaohong要依靠他们各自的名字、性别、生日等属性。
如何让每个实例拥有各自不同的属性?由于Python是动态语言,对每一个实例,都可以直接给他们的属性赋值,例如,给xiaoming这个实例加上name、gender和birth属性:
class Person(object):
pass
xiaoming=Person();
xiaohong=Person();
xiaoming.name="小明"
xiaoming.age=12
xiaoming.grade=3
xiaohong.name="小红"
xiaohong.age=19;
xiaohong.sex="女"
print(xiaoming)#地址
print(xiaohong)#地址
print(xiaoming.name)#小明
print(xiaoming==xiaohong)#False
13.4. Python中初始化实例属性
在定义 Person 类时,可以为Person类添加一个特殊的init()方法,当创建实例时,init()方法被自动调用,我们就能在此为每个实例都统一加上以下属性:
class Person:
def __init__(self,name,sex,age):
self.name=name;
self.sex=sex;
self.age=age;
person1=Person("小明","男",19);
person2=Person("小红","女",20);
print(person1.name,person1.sex,person1.age);#小明 男 19
print(person2.name,person2.sex,person2.age);#小红 女 20
init()方法,在创建一个对象时默认被调用,不需要手动调用init(self)中,默认有1个参数名字为self,如果在创建对象时传递了2个实参,那么init(self)中出了self作为第一个形参外还需要2个形参,例如init(self,x,y)
init(self)中的self参数,不需要开发者传递,python解释器会自动把当前的对象引用传递进去
13.5. Python中访问限制
我们可以给一个实例绑定很多属性,如果有些属性不希望被外部访问到怎么办?
Python对属性权限的控制是通过属性名来实现的,如果一个属性由双下划线开头(__),该属性就无法被外部访问
class Person(object):
def __init__(self, name, score):
self.name = name
self.__score = score
p = Person('Bob', 59)
print(p.name,p._score);
但是,如果一个属性以"xxx"的形式定义,那它又可以被外部访问了,以"xxx"定义的属性在Python的类中被称为特殊属性,有很多预定义的特殊属性可以使用,通常我们不要把普通属性用"xxx"定义。
13.6. python中定义实例方法
一个实例的私有属性就是以__开头的属性,无法被外部访问,那这些属性定义有什么用?
虽然私有属性无法从外部访问,但是,从类的内部是可以访问的。除了可以定义实例的属性外,还可以定义实例的方法。
实例的方法就是在类中定义的函数,它的第一个参数永远是 self,指向调用该方法的实例本身,其他参数和一个普通函数是完全一样的:
class Person:
def __init__(self,name,age):
self.__name=name
self.age=age
def getName(self):
return self.__name;
person1=Person("张三",19)
print(person1.getName())
13.7. python中创建类属性
类是模板,而实例则是根据类创建的对象。
绑定在一个实例上的属性不会影响其他实例,
但是,类本身也是一个对象,如果在类上绑定一个属性,则所有实例都可以访问类的属性,并且,所有实例访问的类属性都是同一个!
也就是说,实例属性每个实例各自拥有,互相独立,而类属性有且只有一份。
class Person:
#声明address地址
address="earth"
def __init__(self,name,age):
self.name=name
self.age=age
person1=Person('zhangsan',19)
print(person1.address)#earth
print(Person.address)#earth
13.8. python中定义类方法
和属性类似,方法也分实例方法和类方法。
在class中定义的全部是实例方法,实例方法第一个参数 self 是实例本身。
class Person(object):
count=0
@classmethod
def howMany(cls):
return cls.count
def __init__(self,name):
self.name=name
Person.count=Person.count+1
print(Person.count,"-----------")
person1=Person("张三");
print(person1.howMany())#1
print(Person.howMany())#1
十四、Python中继承
14.1. 继承概念
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。
通过继承创建的新类称为子类或派生类,被继承的类称为基类、父类或超类。
14.2. 为什么要继承
- 新类不必从头编写,代码的重用
- 新类从现有类继承,就自动拥有了现有类的所有功能
- 新类只需要编写现有类缺少的新功能
在程序中,继承描述的是事物之间的所属关系,例如猫和狗都属于动物.
image.png
14.3. 继承特点以及单继承
子类在继承的时候,在定义类时,小括号()中为父类的名字
父类的属性、方法,会被继承给子类
class Dog(object):
def __init__(self,name,color="黄色"):
self.name=name
self.color=color
def run(self):
print("%s在跑着"%self.name)
class JinMao(Dog):
def setNewName(self,name):
self.name=name
def eat(self):
print("%s在吃饭,颜色是%s"%(self.name,self.color))
dog1=JinMao("大黄")
dog1.run()
dog1.setNewName("小阿黄")
dog1.eat()
说明:虽然子类没有定义init方法,但是父类有,所以在子类继承父类的时候这个方法被继承了,所以只要创建子类的对象,就默认执行了这个init方法.
14.4. 多继承
class Ma(object):
def printMa(self):
print("ma的特性")
class Lv(object):
def printLv(self):
print("lv的特性")
class LuoZi(Ma,Lv):
def printLuo(self):
print("骡子的特性")
luo=LuoZi()
luo.printLuo()
luo.printLv()
luo.printMa()
14.5. 多继承同名方法调用
class Ma(object):
def printMa(self):
print("ma的特性")
def run(self):
print("万马奔腾")
class Lv(object):
def printLv(self):
print("lv的特性")
def run(self):
print("万驴奔腾")
class LuoZi(Ma,Lv):
def printLuo(self):
print("骡子的特性")
luo=LuoZi()
luo.run()
print(LuoZi.__mro__)
先继承哪个,就调用哪个的方法
关于Python类的多继承中的mro属性使用的C3算法以及继承顺序解释
14.6. 方法的重写及调用父类方法
#方法的重写
class Animal(object):
def __init__(self,name,sex,color):
self.name=name
self.sex=sex
self.color=color
def play(self):
print("动物都有各自的玩法")
class Cat(Animal):
def __init__(self,name,sex,color,age):
#super代表父类
super().__init__(name,sex,color)
self.age=age
#方法的重写/覆盖
def play(self):
super().play()
print("%d岁的猫喜欢爬墙"%self.age)
c=Cat("小花","母","花色",8)
c.play()#猫喜欢爬墙
print(c.name,c.sex)
14.7. 类属性和对象属性
类属性就是类(类对象)所拥有的属性。它被类和所有对象所拥有。对于共有类属性,在类外可以通过类对象和实例对象访问。
- 类属性
class Dog(object):
name = "Tom"
__age = 10
print(Dog.name)#正确
print(Dog.__age)#错误,__age属于私有属性,不能在外边访问
d=Dog()
print(d.name)#正确
print(d.__age)#错误,__age属于私有属性,不能在外边访问
- 对象属性
def __init__(self,name):
self.name=name
print(Dog.name)#Tom
d=Dog("大黄",19)
print(d.name)#大黄
print(d.getAge())
def getAge(self):
return self.__age
14.8.python中多态(了解)
类具有继承关系,并且子类类型可以向上转型看做父类类型,如果我们从 Person 派生出 Student和Teacher ,并都写了一个 whoAmI() 方法,在一个函数中,如果我们接收一个变量 x,则无论该 x 是 Person、Student还是 Teacher,都可以正确打印出结果:这种行为称为多态。
方法调用将作用在 x 的实际类型上。s 是Student类型,它实际上拥有自己的 whoAmI()方法以及从 Person继承的 whoAmI方法,但调用 s.whoAmI()总是先查找它自身的定义,如果没有定义,则顺着继承链向上查找,直到在某个父类中找到为止。
class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
def whoAmI(self):
return 'I am a Person, my name is ' + self.name
class Student(Person):
def __init__(self, name, gender, score):
super().__init__(name, gender)
self.score = score
def whoAmI(self):
return 'I am a Student, my name is ' + self.name
class Teacher(Person):
def __init__(self, name, gender, course):
super(Teacher, self).__init__(name, gender)
self.course = course
def whoAmI(self):
return 'I am a Teacher, my name is '+ self.name
p = Person('Tim', 'Male')
s = Student('Bob', 'Male', 88)
t = Teacher('Alice', 'Female', 'English')
print(p.whoAmI())
print(s.whoAmI())
print(t.whoAmI())
14.9.python中多重继承(了解)
除了从一个父类继承外,Python允许从多个父类继承,称为多重继承。
class A(object):
def __init__(self, a):
print ('init A...')
self.a = a
class B(A):
def __init__(self, a):
super().__init__(a)
print ('init B...')
class C(A):
def __init__(self, a):
super().__init__(a)
print ('init C...')
class D(B, C):
def __init__(self, a):
super().__init__(a)
print ('init D...')
d=D("--");
# init A...
# init C...
# init B...
# init D...
十五、Python中异常
15.1. 什么是异常?
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
一般情况下,在Python无法正常处理程序时就会发生一个异常。
异常是Python对象,表示一个错误。
当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
#演示各种异常情况
#第一个异常,数学异常
# ZeroDivisionError: division by zero <<ArithmeticError ctrl+/快速注释
# i=1/0
#第二个异常,类型转换错误
# TypeError: must be str, not int
# age=int(input("请输入年龄"))
# print("年龄是"+age)
#第三个异常:文件异常
# FileNotFoundError: [Errno 2] No such file or directory: 'aa.txt'
# file=open("aa.txt","r")
# file.write("哈哈")
# file.close()
#第四个异常 未定义异常
# NameError: name 'num' is not defined
# print(num)#编译错误
15.2.异常处理
捕捉异常可以使用try/except语句。
try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。
如果你不想在异常发生时结束你的程序,只需在try里捕获它。
try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。
如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。
如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印缺省的出错信息)。
如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。
15.3.异常效果
try:
i=1/0
except:
print("出现错误")
else:
print("一切正常")
try:
i=1/0
except ArithmeticError:
print("出现数学错误")
except ModuleNotFoundError:
print("model找不到")
else:
print("一切正常")
15.4.Try-finally 语句
try:
i=1/0
except:
print("出现错误")
else:
print("一切正常")
finally:
print("无论如何都会执行")
15.5.主动触发异常
我们可以使用raise语句自己触发异常
raise语法格式如下
i=1;
if i<10:
raise Exception("数字i不能小于10")
#异常触发后,后边代码就不会执行
#抛出异常
class Person(object):
def __init__(self,name,age):
self.name=name
self.__age=age
def setAge(self,age):
if age<0 or age>150:
raise Exception("年龄非法")
else:
self.__age=age
def getAge(self):
return self.__age
try:
p=Person("张三",18)
p.setAge(190)
except Exception as result:
print(result)
十六、Python单元测试
16.1. 单元测试框架Unittest介绍
TestCase:一个测试用例,或是一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代码(run)以及测试后环境的还原(tearDown)。
单元测试(unittest)的本质也就在这里,一个测试用例是一个完整的测试单元,通过运行这个测试单元,可以对某一个问题进行验证。
TestSuite:多个测试用例TestCase集合在一起,就是TestSuite,而且TestSuite也可以嵌套TestSuite。
TestLoader:用来加载TestCase到TestSuite中的,其中有几个loadTestsFrom__()方法,就是从各个地方寻找TestCase,创建它们的实例,然后add到TestSuite中,再返回一个TestSuite实例。
TextTestRunner:是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法。测试的结果会保存到TextTestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息。
整个流程:首先是要写好TestCase,然后由TestLoader加载TestCase到TestSuite,然后由TextTestRunner来运行TestSuite,运行的结果保存在TextTestResult中,整个过程集成在unittest.main模块中。
步骤:
- 导入unittest模块
- 当前测试类继承unittest.TestCase,相当于当前利用unittest创建了一个test case,这个test case是能够被unittest直接识别。
- 写setUP(),主要是打开浏览器和打开站点
- 写一个test_search()用例写搜索的代码
- 写tearDown(),主要是浏览器退出操作
16.2. unittest的简单介绍及使用
一个完整的测试脚本包含:
- import unittest
- 定义一个继承自unittest.TestCase的测试用例类,相当于当前利用unittest创建了一个test case,这个test case是能够被unittest直接识别。
- 定义setUp和tearDown,在每个测试用例前后做一些辅助工作。
- 定义测试用例,名字以test开头。
- 一个测试用例应该只测试一个方面,测试目的和测试内容应很明确。主要是调用assertEqual、assertRaises等断言方法判断程序执行结果和预期值是否相符。
- 调用unittest.main()启动测试
- 如果测试未通过,会输出相应的错误提示。如果测试全部通过则不显示任何东西,也可以添加-v参数显示详细信息。
# -*- coding: utf-8 -*-
import unittest
class PythonunitTest(unittest.TestCase):
def setUp(self):
print("---测试初始化工作---")
def testF(self):
i=1+1
print(i)
def tearDown(self):
print("---测试扫尾工作----")
if __name__ == "__main__":
unittest.main()
16.3.断言
image.png# -*- coding: utf-8 -*-
import unittest
class PythonunitTest(unittest.TestCase):
def setUp(self):
print("---测试初始化工作---")
def testF(self):
self.assertEqual(5+5,10);
self.assertTrue(1==1)
self.assertFalse(1==2)
def tearDown(self):
print("---测试扫尾工作----")
if __name__ == "__main__":
unittest.main()
16.4.TestSuite
TestSuite:
而多个测试用例TestCase集合在一起,就是TestSuite,而且TestSuite也可以嵌套TestSuite。
TestLoader:
用来加载TestCase到TestSuite中的,其中有几个loadTestsFrom__()方法,就是从各个地方寻找TestCase,创建它们的实例,然后add到TestSuite中,再返回一个TestSuite实例。
TextTestRunner:
是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法。
import unittest
class Test1(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def test_one(self):
print("test1中第一个测试案例-----")
def test_two(self):
print("test1中第二个测试案例----")
class Test2(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def test_one(self):
print("test2中第一个测试案例-----")
def test_two(self):
print("test2中第二个测试案例-----")
16.5.新建一个py文件
if name == 'main':
suite = unittest.TestSuite()
# tests = [Test1("test_one"), Test1("test_two"), Test2("test_one")]
# suite.addTests(tests)
suite.addTest(Test1('test_one'))
runner = unittest.TextTestRunner(verbosity=2)
runner.run(suite)
如果想全部加载到testSuite中
suite.addTest(unittest.TestLoader().loadTestsFromTestCase(PythonTest1))
suite.addTest(unittest.TestLoader().loadTestsFromTestCase(PythonTest2))
16.6.总结
1.unittest是Python自带的单元测试框架,我们可以用其来作为我们自动化测试框架的用例组织执行框架。
2.unittest的流程:写好TestCase,然后由TestLoader加载TestCase到TestSuite,然后由 TextTestRunner来运行TestSuite,运行的结果保存在TextTestResult中,我们通过命令行或者 unittest.main()执行时,main会调用TextTestRunner中的run来执行,或者我们可以直接通过 TextTestRunner来执行用例。
3.一个class继承unittest.TestCase即是一个TestCase,其中以 test 开头的方法在load时被加载为一个真正的TestCase。
4.verbosity参数可以控制执行结果的输出,0 是简单报告、1 是一般报告、2 是详细报告。
5.可以通过addTest和addTests向suite中添加case或suite,可以用TestLoader的loadTestsFrom__()方法。
6.用 setUp()、tearDown()、setUpClass()以及 tearDownClass()可以在用例执行前布置环境,以及在用例执行后清理环境
7.我们可以通过skip,skipIf,skipUnless装饰器跳过某个case,或者用TestCase.skipTest方法。
8.参数中加stream,可以将报告输出到文件:可以用TextTestRunner输出txt报告,以及可以用HTMLTestRunner输出html报告。
十七、HTMLTestRunner
对于unittest框架,运行后,测试结果不便于查看,同时多个case存在的时候,可能会导致case result记录不正确的情况。
为此,引入了HTMLTestRunner.py,它是Python标准库unittest模块的一个扩展。它可以生成直观的HTML测试报告。
17.1.将HTMLTestRunner.py拷贝到当前项目下
17.2.新建一个py类
if name == 'main':
suite = unittest.TestSuite()
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(Test1))
# 定义生成测试报告的名称
filename1=r""+str(time.strftime('%Y%m%d%H%M%S'))+".html"
fp = open(filename1, 'wb')
# 定义测试报告的路径,标题,描述等内容
runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title=u'自动化测试报告',description=u'自动化测试报告')
runner.run(suite)
网友评论