【python】

1.编译型和解释型

        编译器软件:将书写的代码转换成一个二进制文件,优点是执行效率高,缺点是代码存在编码错误的时候,就不能产生中间文件。如:c.        

        解释型软件:在代码执行的时候,将代码转换未二进制,边执行边转换(解释),优点是代码从上到下执行,后续代码的错误不会影响前面代码的执行。如js,python,php等

2 注释

        注释是对代码解释说明的文字,不会执行,可以增强代码可读性

        单行注释:#,快捷键ctrl /(可以先选中多行,再按快捷键,会给每行加上或取消注释)

        多行注释:三对双引号或者三对单引号

3 代码中的波浪线

        红色:代码的错误,必须处理,代码才能继续执行(代码没有写完也可能有红色波浪线)

        灰色:不会影响代码的正常执行(如PEP8要求注释以# + 空格开始,如果打上#但是忘记加上空格,就会提示灰色波浪线。其中PEP8是python代码的书写规范,如果不按规范书写,就会给灰色波浪线。我们可以在书写完全部代码后,按下快捷键ctrl + alt +L 来按照PEP8自动化格式代码)

        绿色:不会影响代码的正常执行。常出现在引号中,认为你书写的内容部属一个单词。

4 变量

        作用:是用来存储数据的(在程序代码中出现的数据,想要保存下来使用,就必须使用变量

        变量注意事项:必须先定义后使用

        定义变量:变量名=变量值

        使用变量:定义变量之后,直接使用变量名就可以了

        起名规范(标识符规则):必须由字母数字和下划线构成,并且不能以数字开头,不能使用python中的关键字(python自带的已经使用的标识符,具有特殊作用),区分大小写

        建议性命名:驼峰命令法(大驼峰如MyNameIs和小驼峰myNameIs),下划线连接法(每个单词之间使用下划线连接)

5 运行代码的方式

        第一种方式是在命令行窗口(cmd打开),输入[python  要执行的python文件的路径(文件格式为.py)]

        第二种方式是先进入到存储要运行的Python文件的位置,然后右击运行命令行,输入【python python文件名】

        第三种方式是使用可视化工具直接run

6 数据类型

  • 数字类型 
    • 整形int:就是整数,不带小数的数
    • 浮点数float:就是小数
    • 布尔类型bool:只有两个值True和False(注意大小写)
    • 复数如3+4i
  • 非数字类型
    • 字符串str:使用引号引起来的就是字符串
    • 列表list: 如[1,2,3]
    • 元组tuple:如(1,2,3,4)
    • 字典dict:如{‘name':'Cai'}

        type(变量):可以获取变量的数据类型,如果要输出则使用print(tyoe(变量))

7 输入

        input():获取用户使用键盘录入的内容

        常常使用的形式是:变量=input('提示信息’)

        代码从上到下执行,遇到input函数之后,会暂停执行,等待用户的输入,如果不输入会一直等待。在输入过程中,遇到回车表示本次输入结束 。会自动将输入的内容转换成字符型(通过type(变量)查看类型为[class 'str'])保存到左边的变量中。        

8 类型转换

        语句:变量=要转换为的类型(原数据)

        注意:数据类型转换,不会改变原来数据的  类型,会生成一个新的数据类型)

int()将其他类型转换为int类型

        可以将float类型的数字转换为整型

        可以将 整数型的字符串转换为 整型

float() 将其他类型转换为 浮点型

        可以将int类型转换为浮点型 

        可以将数字类型的字符串(整数类型和小数类型)转换为浮点型

str()将其他类型转换为字符串类型

        任何其他类型都可以使用str()转换为字符串类型

                      

9 格式化输出     

        print()可以使用逗号输出多个内容

%d,%f,%s分别是整数小数字符串类型占位

        例1:输出“我的名字是xx,年龄是xxx,身高是xxx"

        print('我的名字是%s,年龄是%d,身高是%f) % (name,age,height))

        例2:从例1的实际输出可以看出,%f默认保留小数位为6位,要是想保留2为小数

        print('我的名字是%s,年龄是%d,身高是%2f) % (name,age,height));

        例3:保留一位小数

        print('我的名字是%s,年龄是%d,身高是%1f) % (name,age,height))

        例4:将1输出为000001

        print('我的学号是%06d' % num) #%0nd将n换成具体数字后,就表示整数一共几位

        例5:使用%

        print('我的成绩是前10%%‘)

10 f 字符串格式化

        注意:要想使用此方法,python版本需要>=3.6才可

        使用:在字符串前加上小f或者大F,占位符号变更为{},

例子:(\n表示换行)

print(  f’我的名字是{name},\n我的年龄是{age:},\n我的身高是{height:3f},我的学号是{stu_num:06d}我的成绩在前{num}%')

11 字符串.format()格式化字符串

        使用{}占位,

        语法: ‘ {},{},{},....’.format(变量1,变量2,变量3....)

         

12 快捷键

        撤销ctrl+z

        删除一行ctrl+x

        复制粘贴一行:ctrl+d

        快速在代码下方新建一行:shift+enter

13 运算符

        算数运算符:+,-,*,\ (得到的是浮点类型), // 求商,% 取余 ,** 幂运算

        比较运算符:>,< ,>=,<=,==,

        逻辑运算符:and(第一个条件为false的时候不再继续判断),not,or(第一个条件为true的时候不再继续判断)

       赋值运算符:=将等号右边的值保存到等号左边的变量中

        复合运算符:+=,-=,/=,*=

14 if...elif...else

       语法结构:

        if 判断条件:

                书写条件成立(真)执行的代码

        elif 判定条件1:

        elif 判定条件2:

        elif 判定条件n:      

        else :

                书写条件不成立(假)执行的代码

        if是一个关键字,和后续判断条件之间需要一个空格

        判断条件后边需要一个冒号,else也需要

        冒号之后回车,代码需要缩进,在pycharm中会自动缩进,一般是四个空格,或者一个tab键

        if代码块的代码,要么都执行,要不都不执行

        只有if不成立了,才会去判断elif

        

age=input('你的年龄是')

if int(age)>18:

        print('可以进去网吧‘)

else

        print(’不能进去网吧‘)

name=input('你的名字是')

if name=='admin':

        print('欢迎admin')

pwd=input('你的密码是')

if name=='admin' and pwd=='123':

        print(f'欢迎{name}登入’)

else :

        print('错误‘)

猜拳游戏:

import random

player=input('请出拳头1,剪刀2,布3)

computer=random.randint(1,3)

if player==1  and  computer==2 or player==12 and  computer==3 or player==3 and  computer==1:

    print(玩家胜利)

elif  player ==computer:

    print(电脑获胜)

else:

    print(打平了)

15 debug

        主要作用:查看代码的执行步骤

        在pycharm中,代码和行号之间点击,出现小红点即打断点,再次点击小红点会取消断点

        断点的位置,一般来说会在代码的第一行(在程序运行的时候,想要在什么地方停下来)

        注意点:可能会出现的bug(pychrm软件的问题):代码中只有一个断点的时候不能debug调试查看代码执行过程,解决方案是在代码其他任意地方多加一个断点

        

16  while循环

        循环就是让指定代码重复的执行

        在程序开发中一共有三种流程方式:顺序,分支,循环

        语法:

                while 判断条件:

                        循环语句

        死循环:一般由写代码的人不小心造成的bug,代码会一直运行下去

        无限循环:写代码的人故意无限制的去执行,代码会一直不停的运行下去。常用场景是书写循环的时候不确定循环要执行多少次,所以一般会在循环当中添加一个if判断,然后使用break来终止循环。

17 for循环

        语法:

        for 变量名  in  容器:

                重复执行的代码

        容器可以是:字符串str,列表list,元组tuple,字典dict

  18 range函数

        range()是python自带的函数,作用是可以生成【0,n)之间的整数,不包含n,一共循环n次。

        想让for循环几次n就写多少

        range(n,m)是range的变形,作用是获取n到m之间的整数,不包含m。

19 字符串

        使用单引号,双引号,三引号定义

        字符串本身含有双引号,则在定义的时候不能使用双引号;字符串本身含有单引号,则在定义的时候不能使用单引号。若实在想使用,则使用转义字符\,但如在字符串前面添上r' ',则表示是原生字符串,不对转义字符进行转义

        下标:从左到右从0开始,从右到左-1开始

        长度:len(字符串名)

19.1 字符串切片

        切片:字符串[start:end:step],start是开始的下标,end是结束位置的下标(不能取到),例如[1:5:2]就是1 3 。

        切片会得到一个字符串,既可以获取字符串中多个字符。

        str1='abcdefg'

        print(str1[0:3:1])#abc

        print(str1[0:3])#abc,如果步长为1可以不写,最后一个冒号可以不写

        print(str1[:3])#abc如果开始位置为0,可以不写,但是冒号必须有

        print(str1[4:7])#efg

         print(str1[-3:7])#efg

         print(str1[4:7])#efg 

          print(str1[4:])#efg如果最后一个字符也要取,可以不写,但是冒号一定要有

        print(str1[:])#如果取全部字符,可以不写,但是冒号一定要有

        注意有种特殊使用:步长为负数,开始和结束不写,表示倒置字符串

        print(str1[: :-1]

19.2 find查找字符串

        语法:字符串.find(sub_str,start,end)

        sub_str : 要查找的小的字符串

        start:开始位置,从哪个下标开始找,一般不写,默认是0

        end:结束位置,查找哪个下标结束,一般不写默认是len()

        如果找到了则返回sub_str第一次出现的正数下标,如果没找到就返回-1

 str1='and it and  cai and python'       

在字符串中查找'and'

num=str1.find('and')

print(num)

在字符串中查找第二个and出现的下标,从第一个之后开始找

num1=str1.find('and',num+1)

print(num1)

在字符串中查找第三个and出现的下标,从第二个之后开始找

num2=str1.find('and',num1+1)

print(num2)

 19.3 replace替换字符串

             字符串.replace(oldstr,newstr,count),表示将字符串oldstr替换为newstr,进行count次,如果count不写默认全部替换。

19.4 split字符串的拆分

        字符串.split(sep,max-split)表示将字符串按照sep进行分割。

        其中sep表示字符串按照什么分割,默认是空白字符(空格,换行,tab键),max-split是分割次数,一般不写,全部分割。

        返回结果是列表

        如果sep不写想要指定分割次数,则使用字符串.split(max_split=n),n是次数。

19.5  字符串拼接 

        字符串.join(列表)是将字符串插入到列表中每相邻的两个数据之间,列表中的数据使用逗号隔开,

        括号里的内容主要是列表也可以是其他容器,列表的数据都必须是字符串,否则会报错。

20 列表(定义,添加,查询,修改,排序)

        列表在其他语言中叫数组

        定义语法:

        法1:数组名=[数据之间用英文逗号隔开]

        法2:数组名=list()

        类型转换:

        list1=list('hello')转换字符串会将字符串中的每个字符作为一个数据存入列表

        print(type(list1),list1)

        下标规则和切片操作与字符串使用方法一样,区别是列表的切片得到的是列表

        添加:列表.append(数据)

        查询:列表.index(数据),列表.count(数据)

        修改:列表[下标]=数据,注意字符串中的字符不能使用下标修改,如果指定的下标不存在代码会报错。

        排序:列表.sort()表示从小到大排序,列表.sort(reverse=True)表示从大到小排序

20.1  查找列表中数据下标的方法

        在字符串中使用find方法查找下标 不存在返回-1,而在列表中使用index()方法

        列表.index(数据,start,end)使用和find方法一样。

        同时在字符串中也有index方法,区别的地方在于返回第一次出现的下标,如果找不到直接报错。

20.2 in用于判断是否存在

        判断容器中某个数据是否存在可以使用in关键字

        语法:数据 in 容器,如果存在则返回True,不存在则返回False

20.3 count()查找找统计出现的次数

·        语法:列表.count(数据),返回数据出现的次数

20.4 添加数据

20.4.1尾部添加(最常用)

        语法:列表.append(数据),将数据添加到列表的尾部

        返回:返回的None(关键字,空),一般就不再使用 变量 来保存返回的内容,想要查看添加后的列表,需要打印的是列表

20.4.2 指定下标位置添加

        语法:列表.insert(下标,数据),在指定的下标位置添加数据,如果指定的下标位置本来有数据,原数据会后移

        返回:返回的None(关键字,空),一般就不再使用 变量 来保存返回的内容,想要查看添加后的列表,需要打印的是列表

20.4.3列表合并

        语法:列表1.extend(列表2),将列表2中所有数据逐个添加到列表1的尾部

        返回: 返回的None(关键字,空),一般就不再使用 变量 来保存返回的内容,想要查看添加后的列表,需要打印的是列表

20.5 列表删除     

        在列表中删除中间的数据,那么后面的数据会向前移动

20.5.1  根据下标删除

        语法:列表.pop(下标),下标不写,默认删除最后一个数据

        返回的是删除的数据

20.5.2 根据数据值删除

        语法:列表.remove(数据值),根据数据值删除数据

        返回:None

        注意,删除的数据不存在会报错

20.5.3 清空数据(一般不用)

        语法:列表.clear

20.6 列表反置

        字符串中反转倒置是:字符串[ : :-1]

          列表中反转和倒置:

        1.列表[ : :-1]:使用切片的方法,会得到一个新列表,原列表不会发生改变

        2.列表.reverse() 直接修改原列表,返回None

20.7 列表的复制

        使用场景:有一个列表,需要修改操作列表中的数据,修改之后,需要和原来的数据进行对比,即原来的数据不能改

        语法1:使用切片:变量=列表[ : ]

        语法2:使用copy:变量=列表.copy()

20.8 列表嵌套

        person_info=[['zhangshan','18','功能测试'],['lisi','20','自动化测试']]

         print(person_info)  #['zhangshan','18','功能测试'],['lisi','20','自动化测试']

        print(len(person_info) ) #2

        print(person_info[0]) #  ['zhangshan','18','功能测试']

        print(person_info[0][0]) #'zhangshan'

         print(person_info[0][0][0]) #'z'

        

21  元组

        元组tuple的特点和列表非常相似:元组可以存放任意类型的数据,元组中可以存放任意多个数据;区别在于元组中的数据内容不能改变,列表中的数据可以改变,元组使用(),列表使用[]

        元组运用:在函数的传参或者返回值中使用,保证数据不会被修改

        定义:使用 类实例化 或者 直接使用()方式

1.类实例化的方式

1.1 定义空元组(不会使用)

tuple1=tuple()

print(type(tuple1),tuple1) #<class 'tuple'> ()

1.2类型转换

tuple2=tuple([1,2,3])

print(tuple2)

转换字符串

tuple3=tuple('hello')

print(tuple3)

2.直接使用()定义

tuple4=(1,'小王',3.14,False)

print(tuple4)

3.特殊点,定义只有一个数据的元组时,数据后边必须有一个逗号

tuple5=(1,)

print(tuple5)

        常用方法:由于在元组中的数据不能修改,所以只有查看的方法

1.在元组中也可以使用切片获取数据

2.在元组中存在index方法

3.在元组中存在count方法

4.在元组中可以使用in操作

以上方法和列表中一样

22 字典

        字典dict,字典中的数据由键值对组成(键表示数据的名字,值就是具体的数据)

        定义:变量={key:value, key :value....}

        一个字典中的键是唯一的,不能重复的,值可以是任意数据

        字典里的键一般都是字符串,可以是数字,不能是列表。

定义:

1.使用类实例化的方法

dict1=dict()

print(type(dict),dict1    )# <class 'dict'> {}

dict()不能转列表和元组,字符串

2.使用{}定义

2.1空字典

dict2={}

peint(type(dict2),dict2) #<class 'dict> {}

2.2非空字典,小明('name') 18('age') 1.71('height') True(is_men)

dict3={'name':小明,'age':18,'height':1.71,'is_men':True}

print(dict3)

print(len(dict3)) 

增加和修改操作:

语法:字典[键]=数据值

1.如果键已经存在,就是修改数据值

2.如果键不存在,就是添加数据(即添加键值对)

dict1={'name':小明,'age':18,'height':1.71,'is_men':True}

#添加性别信息

dict1['sex']='男'

#修改信息

dict['age']=19

删除:

删除指定键值对:del 字典[键] 或 字典.pop(键)

清空:字典.clear()

查询(根据键获取对应的值):

字典没有下标的概念,想要获取数据值,需要使用key(键)来获取

1.字典[键],如果键存在返回键对应的数据值,如果不存在,会报错

2.字典.get(键,数据值),数据值一般不写,默认是None,如果键存在,返回对应的数据值,如果不存在,返回的是括号书写的数据值

一般建议使用get方法

dict3={'name':小明,'age':18,'height':1.71,'is_men':True}

print(dict3.get('sex',‘保密’)

遍历字典:        

1.遍历字典的值

语法:#字典.values可以获取字典中所有的值

for 变量 in 字典.values():

        print(变量)

2.遍历字典的键

语法1:

for 变量 in 字典:

        print(变量)

语法2:

for 变量 In 字典.keys():

        print(变量)

3.遍历字典的键值对

语法:#字典.items()获取键值对

for 变量1,变量2 in 字典.items():

        print(变量1,变量2)

23 容器部分总结

        1.字符串,列表,元组 支持加法运算

        str1='hello'+'world' #'hello world'

        list1=[1,2]+[3,4] #[1,2,3,4]

        tuple1=(1,2)+(3,4) #(1,2,3,4)

        2.字符串,列表,元组 支持乘 一个数字

        'hello' * 3 #'hello hello hello'

        [1,2] * 3=[1,2,1,2,1,2]

        (1,2) * 3=(1,2,1,2,1,2)

        3.len()在任何容器中均能使用

        4 in 关键字在任何容器中都能使用,注意,容器中判断是字典的键是否存在

24 列表去重

        方法1:

        思路 :遍历原来列表中的数据判断是否在新列表中存在,如果不存在,就放进新列表,如果存在则不管

        遍历使用for实现

        判断是否存在可以使用in

        存入数据使用:append

        方法2:

        思路:使用集合 set,特点是集合中不能使用重复的数据(如果有重复的数据会自动去重),使用set()类型将列表转换为集合类型,再使用list()类型将集合转换为列表

        缺点:不能保证数据再原列表中出现的顺序,一般来说,也不考虑这件事

法一:

mylist=[1,2,3,3,2,1,2,3,1]

newlist=[]

for i in mylist:

        if i not in newlist:

                newlist.append(i)

print(newlist)

法二:

mylist=[1,2,3,3,2,1,2,3,1]

set(mylist)

list(set(mylist)

25 函数

        好处:减少代码的冗余,重复的代码不用多写

        函数必须先定义后使用:

        定义语法:

        def 函数名():

                函数中的代码

        1.def 是关键字,是用来定义函数的,define的缩写

        2.函数名需要遵守标识符的规则

        3处于def缩进中的代码,称为函数体

        4.函数定义的时候,函数体中的打开吗不会执行,在调用的时候才会执行

         函数使用:

        语法:函数名()

文档注释:

        文档注释的本质还是注释,只不过书写的位置和作用比较特殊

        书写位置:在函数名下方使用,三队双引号进行的注释

        作用:告诉别人这个函数如何使用

        查看:在调用的时候,将光标放到函数名上,使用快捷键ctrl + q直接查看,使用ctrl+b转到函数声明中查看 

函数参数

        def mysum(num1,num2):#num1,num2是函数定义时候的参数,起到占位符的作用,没有具体的数据值,简称 形参

                print(num1+num2)

        mysum(1,2) #函数调用时括号中的数据会传递给形参,是具体的数据值,称为实际参数,简称 实参,调用时参数类型与顺序和个数,都要与定义的函数一一对应。

完整的参数顺序:

        def 函数名(普通函数, *args,缺省参数,  **kwargs):

        

函数返回值return:

        return关键字只能在函数中使用

        作用:代码执行遇到return,会结束函数的执行

        场景:需要使用函数处理过的数据

        def 函数名字1():#返回值None

                pass #代码中没有return

        def 函数名字2():#return后面没有数据,返回值None

               return 

        def 函数名字3():#返回值是xx

                return xx

函数返回多个数据值

        函数想要返回一个数据值,使用return关键字

        将多个数据值组成容器进行返回,一般是元组(组包)

def cal(a,b):

        num1=a+b

        num2=a-b

        return num1,num2

方法一:

result=cal(10,5)

print(result,result[0],result[1])  #输出(15,5) 15 5

方法二:直接拆包

x,y=cal(10,5)

print(x,y)

 函数传参:

        包括位置传参和关键字传参,还有 混合使用

        位置传参:在函数调用的时候,按照形参的顺序,将实参值传递给形参

        关键字传参:在函数调用的时候,指定数据值给到哪个形参

        混合使用:关键字传参必须写在位置传参的后面,不要给一个形参指定多个实参

def func(a,b,c):

        print(f'a:{a},b:{b},c:{c}')

#位置传参

func(1,2,3)

#关键字传参

func(a=2,b=3,c=1)

#混合使用

func(1,3,c=2)

缺省参数:

        缺省参数,默认参数

        1.在函数定义的时候给形参一个默认的数据值,这个形参就变为缺省参数,注意缺省参数的书写要放在普通参数的后面

        2.好处:缺省参数在函数调用的时候,可以传递实数值也可以不传递实数值

多参传递[可变参数/不定长参数]:

        1.不定长位置参数(不定长元组参数)

        在普通参数的前边,加上一个 * ,这个参数就变为不定长参数,这个形参就可以接收任意多个传参的数据,其数据类型是 元组 ,一般写法  * args,其中args表示不定长位置参数的名字

        2.不定长关键字参数(不定长字典参数)

        一般是在普通参数的前边加上两个 * (即  **  ),这个参数就变为不定长关键字参数,这个形参就可以接收任意多个传参的数据,其数据类型是 字典,注意不定长关键字参数要写在所有参数的最后边,一般写法 **kwargs (kwargs表示不定长关键字参数的名字

def func(*args,**kwargs):

        print(type(args),args) #print默认会有换行效果

        print(type(kwargs),kwargs)

        print('-'*30)

func()

func(1,2,3)  #位置传参,数据都给了args

func(a=1,b=2,c=3)   #关键字传参,数据都给了kwargs

func(1,2,3,a=4,b=5,c=6)  #混合传参,前三个数据给了args,后三个给了kwargs)

匿名函数:

        使用lambda关键字定义的函数称之为匿名函数(使用def关键字定义的函数是   标准函数),匿名函数一行只能书写一行代码, 匿名函数的返回值不需要return,一行代码(表达式)的结果就是返回值,也不需要我们主动调用,一般作为函数的参数使用

        语法:lambda 参数:一行代码

  •         分类:
    • 无参无返回值
    • 无参有返回值
    • 有参无返回值
    • 有参有返回值

1.无参无返回值:

def func1():

        print('hello')

等价于 lambda : print ('hello')

调用匿名函数:

func11=lambda : print ('hello')

func11()

不要对匿名函数起名字,要不然就直接使用def就成了

 2.无参有返回值

def func2():

        return 10

lambda : 10

3.  有参无返回值

def func3(a,b):

        print(a)

等价于:lambda   a,b :print(a)

4.有参有返回值

def func4(a,b):

        return a+b

lambda  a,b :a+b

练习:

1.求两个数的积:lambda a,b :a*b

2.定义一个匿名函数,其参数(参数只是一个占位的作用,定义的时候没有具体的数值,形参的类型是由实参决定的)为字典,返回字典中键为age的值

lambda x:x.get('age')或lambda x:x['age']

应用:

匿名函数作为函数的参数,列表中的字典排序

userlist=[

{'name':'zhangsan','age':18},

{'name:'lisi','age':19'},

{'name:'wangwu':,'age':17}

]

#userlist.sort()会报错,因为列表的排序默认是对列表中的数据进行比较大小,而且仅仅可以对 数字类型和字符串类型 进行比大小,对于字典来说,我们需要使用sort函数中key这个参数,来指定字典比较大小的方法,key这个参数需要传递一个函数,一般是匿名函数,字典的排序其实是要指定字典的什么进行排序

userlist.sort(key=lambda x:x['age'])

userlist.sort(key=lambda x:x['age'],reverse=True)

#说明:userlist.sort(key=lambda x:x['age'])这个匿名函数中的参数是 列表中的数据,在sort函数内部,会调用Key这个函数,从列表中获取函数的返回值,对返回值进行比较大小操作

26 变量进阶

        变量的引用:

        1.在定义变量的时候 变量=数据值,python解释器会在内存中开辟两块空间

        2,变量和数据都有自己的空间

        3,日常简单理解,将数据保存到变量的内中中,本质是将数据的地址保存到变量对应的内存中

        4,变量中存储数据地址的行为就是引用(变量引用了数据的地址,简单来说就是变量中存储数据),存储的地址称为引用地址

        5,可以使用id()来获取变量中的引用地址(即数据的地址),如果两个变量的id()获取的引用地址一样,即代表着两个变量引用了同一个数据,是同一个数据

        6.只有赋值运算符=,可以改变变量的引用(等号左边数据的引用)

        7,python中数据的传递,都是传递的引用

a=1 #将数据 1 的地址 存到a对应的内存中

print('a',id(a))

b = a#将 变量 a 的引用保存到变量 b

print('b',id(b))

a=10  #将数据 10  的地址 存到a对应的内存中,即 a 的引用变了

print('a',id(a))

print('b',id(b) #b还是 数据 1 的内存地址

27 可变类型和不可变类型

        数据类型:int float bool str list tuple set dic

        可变不可变是指:数据所在的内村是否允许被修改,允许修改就是可变类型,不允许修改就是不可变类型(不使用=,变量引用的数据中的内容是否会变化,会变化是可变的,不会变化是不可变的)

        可变类型:列表 list,字典 dict,集合 set

                列表.append(),字典.pop(键)

        不可变类型:int float bool str tuple

mylist=[1,2,3]

mylist1=[1,2,3]

print('mylist',id(mylist),id(mylist1))

print('mylist1',id(mylist1))

mylist[1]=10

print(mylist)

print('mylist',id(mylist),id(mylist[1]))

mytuple=(1,2,[3,4])#元组中存储1的地址,2的地址 和 列表的地址

print(mytuple,id(mytuple[-1])

mytuple[-1][0]=10 #修改的是列表中下标为0 的位置的引用地址,列表的地址没变,元组的内容没有变化

print(mytuple,id(mytuple[-1])

#只是把引用地址里面的数字给改变了,但是地址还是没有变

28 组包和拆包

        组包(pack):将多个数据值用逗号连接,组成元组

        拆包(unpack):将容器中的数据值使用多个变量分别保存的过程,注意:变量的个数和容器中数据的个数要保持一致

a=10

b=20

c=b,a  #组包

print(type(c),c)  #输出<class 'tuple'> (10,20)

a,b=c  #拆包

print(a,b)   #输出 10 20

 x,y,z=[1,2,3]

print(x,y,z)  #输出为 1 2 3

        赋值运算符都是先执行等号右边的代码,执行的结果,保存到等号左边的变量

函数中的拆包:

def mysum(*args,**kwargs):

        for i in args:

                num+=i

        for j in kwargs.values():

                num +=j

        print(num)

#需求,mylist=[1,2,3,4],字典mydict={'a':1,'b':2,'c':3,'d':4}

#将字典和列表中的数据使用mysum函数进行求和,该如何传参的问题

mysum(1,2,3,4)

mysum(a=1,b=2,c=3,d=4)

#想要将列表中的数据,分别作为位置参数,进行传参,需要对列表进行拆包操作

mylist=[1,2,3,4]

mysum(* mylist)

#想要将列表中的数据,分别作为关键字参数,进行传参,需要对字典进行拆包操作

mylist=[1,2,3,4]

mydict={'a':1,'b':2,'c':3,'d':4}

mysum(* * mydict)

29 局部变量和全局变量

        局部变量:在函数内部(函数的缩进中)定义的变量,称之为局部变量

  •         特点
    • 局部变量只能在当前函数内部使用,不能在其他函数和函数外部使用,
    • 在不同函数中可以定义名字相同的局部变量,两者之间没有影响
    • 生存周期(生命周期,作用范围):在函数被调用的时候,局部变量被创建,函数调用结束,局部变量被销毁(删除),不能使用
  • 所以函数中的局部变量的值,如果想在函数外使用,则需使用关键字"return",将这个值返回

        全局变量:在函数外部定义的变量,称之为额全局变量

  • 特点
    • 可以在任何函数中读取(获取)全局变量的值
    • 如何在函数中存在和全局变量名字相同的局部变量,在函数中使用的是 局部变量的值(就近)
    • 在函数内部想修改全局变量的引用,需要添加 global 关键字,对变量进行声明为全局变量
    • 生命周期:在代码执行的时候被创建,代码执行结束被销毁

30 print()函数

        end='\n'表示每一个print函数结束,都会打印的内容 (结束符),默认是换行,若想修改使用如print(1,end='  ') print(2)print(3,end=' * ')

        sep='  '表示多个位置参数之间的间隔,修改如下:print(1,2,3,4,5,6,sep='__') print(1,2,3,sep= ' * '

31 面向对象

        面向对象是一个编程思想(写代码的套路)  ,编程思想包括   面向过程  和  面向对象   

        在程序代码中 , 对象 由 类 创建

        类是抽象的概念,对 多个特征和行为相同或者相似的事物的统称,泛指

        对象是具体存在的一个事物,特指

类的组成:

        类名:满足大驼峰命名法,即每个单词的首字母大写

        属性:事物的特征,一般文字中的名词

        方法:事物的行为,一般是动词

步骤:

        1,定义类

        先定义简单的类,不包含属性,使用关键字class

        方法:方法的本质是在class中定义的函数,只不过第一个参数是self

        2.创建对象

        使用 类名()  进行创建

        常用语法:变量=类名() ,这个变量保存的是对象的地址,一般可以称为这个变量为对象

        3.调用方法

        语法:对象.方法名()

class Cat:

        def eat(self):

                print('eat fish')

        def drink(self):

                print('drink water')

blueCat=Cat()

blueCat.eat()

blueCat.drink()

blackCat=Cat()

blackCat.eat()

blackCat.drink()

self的说明:

        从函数语法上来说.self是形参,就可以是任意的变量名,只不过问你习惯性将这个形参协作self

        self是普通的形参,但是在调用的时候没有传递实参值,原因是python解释器在执行代码的时候,自动将调用这个方法的对象传递给self, 

属性:

        1.添加属性:

        分为 外部添加  和 类内部添加, 

        语法:对象.属性名=属性值

        1.1 内部添加

                在内部方法中,self是对象

                self.属性名=属性值

                在类中添加属性一般写做 _init_方法中

        1.2类外部添加

                对象.属性名=属性值 #一般不使用

        

        2.获取属性

        语法:对象.属性名

        2.1内部获取

                在内部,self是对象

                self.属性名

        2.2 外部获取

                对象.属性名

魔法方法:

        在python中有一类方法,以两个下划线结尾,并且在满足某个条件的情况下,会自动调用,这里方法称为魔法方法

1._init_方法

        创建对象之后自动调用,用于给对象添加属性(初始化方法,构造方法)

class  Cat:

        def _init_(self):

                self.name='blueCat'

                self.age=2

        def show(self):

                print({self.name},{self.age})

cat1=Cat()

cat1.show()

2,_str_方法

        

        使用print(对象)打印对象的时候会自动调用,适用于想要打印对象的时候想要查看什么信息,在这个方法里面定义,需注意,这个方法必须返回一个字符串

class  Cat:

        def _init_(self):

                self.name='blueCat'

                self.age=2

        def  _str_(self):

                return "1"

        def show(self):

                print({self.name},{self.age})

cat1=Cat()

cat1.show()

3,_del_方法

        对象对销毁之后自动调用

        

class  Cat:

        def _init_(self):

                self.name='blueCat'

                self.age=2

        def  _str_(self):

                return "1"

        def _str_(self):

                print('没了')

        def show(self):

                print({self.name},{self.age})

cat1=Cat()

cat1.show()

cat2.Cat()

print('代码运行结束')

4.__dict__

        为魔法属性

        可以将对象具有的属性组成字典返回

        使用:对象名.__dict__

实例1:

小明体重70KG,跑步廋0.5KG,吃东西胖1KG

class Person:

        def _init_(self,name,weight):

                self.name=name

                self.weight=weight

        def _str_(self):

                return f"姓名{self.name},"体重"{self.weight}"

        def run(self):

                print(f'{self.name}廋了')

                self.weight-=0.5

        def eat(self):

                print('f{name}胖了')

                self+=1

xm=Person(小明,75)

print(xm)

xm.run()

xm.eat()

实例2:

需求是某web项目登入页面包括:用户名,密码,验证码,登录按钮和登录的方法,书写代码实现上述功能,登录方法使用print输出即可

class LoginPage:

        def _init_(self,username,password,code):

                self.username=username

                self.password=password

                self.code=code

                self.btc='登录'

        def login(self)

                print(f'输入用户名{self.username}')

                print(f'输入密码{self.password}')

                 print(f'输入验证码{self.code}')

                 print(f'点击按钮{self.btn}')

login=LoginPage('admin','123456','8888')

login.login() 

 私有和公有:

        访问控制分为两种权限,公有和私有

        公有权限表示在任意地方可以访问和使用

        私有权限表示只能在当前类的内部使用

        某个属性或者方法,不行在类外部被访问和使用,就将其定义为私有即可        

        测试中,一般不怎么使用的直接公有即可

        开发中会根据需求文档,确定什么作为私有

        如果想要在类外操作私有属性,一般是在类内部定义公有的方法,我们通过这个方法去操作私有属性

class Person:

        def _init_(self,name,age):

                self.name=name #公有

                self._age=age#私有,私有的本质是python解释权执行代码,发现属性名或者方法名前有两个_,会将这个名字重命名,会在这个名字的前面加上_类名前缀,如self.__age变成 self._Peerson__age,如果想在类外打印,可以使用print(xm._person__age),平常时不要用

        def _str_(self):

                return f'{self.name},age:{age}'               

xm=Person('xiaoming',,18')

print(xm)

print(xm._age)

print(xm.name)

 面向对象的三大特性:

        封装,继承.多态

        继承的语法:class  类名(父类名)

        父类又称之为基类,子类又称之为派生类

        继承之后的特点:子类继承父类之后,子类的对象可以直接使用父类中定义的公有属性和方法

        python中对象.方法()调用方法,如果自己的类中有就用本身的,如果没有就去父类找,全没有就报错

        重写:在子类中定义和父类名字相同的方法

        重写的原因:父类中的方法,不能满足子类对象的需求,所以重写

        重写之后的特点:调用子类自己的方法,不再调用父类的方法

        重写分为覆盖和拓展(保留父类中的功能)

        覆盖:直接在子类中定义要覆盖的父类方法就可以

        拓展:在子类定义的父类方法中的适宜位置调用super().方法()

        

        多态:不同的子类对象 调用相同的父类方法,产生不同的执行结果;是调用方法的技巧,不会影响类的内部设计

class Person:

        def work(self):

                print('人需要工作')

class Coder(Person):

        def work(self):

                print('开发人员-->工作是写代码')

class Tester(Person):

        def work(self):

                print('测试人员-->工作是测试项目')

class Company:

        def show_work(worker):

                worker.work()

c=Company()

xw=Coder()

xh=Tester()

c.show_work(xw)

c.show_work(xh)

 实例对象:

        通过  类名()  创建的对象,我们称之为实例对象,简称实例

        创建对象的过程称之为实例化

        每个实例对象都有自己的内存空间,在自己的内存空间中保存自己的属性(实例属性)

类对象:

        类对象 就是类,或者可以认为是类名

        类对象就是 python 解释器在执行的过程中创建的

        类对象的作用:使用类对象创建实例,类对象有且只有一份自己的内存空间,可以保存一些信息

实例属性:

        在init方法中使用self.属性名=属性值 定义,在方法中使用self.属性名  来获取(调用)

类属性:

        在类内部,方法外面直接定义的变量就是类属性,通过   类对象.属性名=属性值  或者  类名.属性名=属性值  来定义,使用  类对象.属性名  或  类名.属性名  获取

使用技巧:找多个对象,来判断这个值是不是一样的,如果都是一样的,同时变化,则一般定义为 类属性,否则就定义为  实例属性

        

练习:

定义一个dog类,定义一个类属性count,用来记录该类创建类几个对象,实例属性name

class Dog:

        count=0 #定义类属性

        def __init__(self,name)

        self.name=name  #实例属性 

        Dog.count++  # 因为每创建一个对象,都需调用一遍__init__

print(Dog.count)

dog1=Dog('xh')

print(Dog.count)

dog2=Dog  #不是创建对象,个数不变

print(Dog.count)

dog3=dog1 #不是创建对象,个数不变

print(Dog.count)

dog4=Dog('xx')

print(dog1.count)

print(dog4.count)

 方法的划分:

        方法,使用def关键字定义在类中的函数就是方法

        实例方法:

        在类中直接定义的方法就是实例方法

        如果在方法中需要使用实例属性(即需要使用self),则这个方法必须定义为 实例方法\       

        调用: 对象.方法名() #不需要给self传参 

        class Demo:

                def func(self):

        类方法:

        在方法的名字上方书写@classmethod装饰器(使用 @classmethod装饰的方法)

        使用前提是方法中不需要使用  实例属性(即self),用到类属性,可以将这个方法定义为类方法(也可以定义为实例方法)       

         调用  : 类名.方法名() #不需要给cls传参,python解释器自动传递  与 实例.方法名()   #不需要给cls传参,python解释器自动传递

        class Demo:

                @classmethod

                def func(cls):#参数一般写作cls,表示的是类对象(即类名)class

        静态方法:

        在方法的名字上方书写@staticmethod装饰器(使用 @staticmethod装饰的方法)

        使用前提是方法中不需要使用  实例属性(即self),也不用到类属性,可以将这个方法定义为静态方法

        调用:类名.方法名  或  实例.方法名

        class Demo:

                @staticmethod

                def func():#参数一般不写

补充:

        哈希(hash):是一个算法,可以对数据产生一个唯一的值(类似于指纹)

        is 可以判断两个对象是不是同一个对象,即  两个对象的引用是否相同

        a is b==>id(a)==id(b)

        ==值用于判断数据值是否相等,is判断引用是否相等 

32 文件

      作用:将数据长期保存下来,在需要的时候使用

        文件中存储的数据都是以2进制的形式存储

        可以根据  "文件中的二进制内容,能否使用记事本软件将其转换为文字   "  将文件分为 文本文件 和二进制文件 两种

        文本文件能使用记事本打开(能用记事本转换为文字,如txt,md,py,html,css,js,json),二进制则不能  (如 exe,mp3,mp4,jpg,png)

        文件操作的步骤:1.打开文件(将文件从磁盘/硬盘 )  中读取到内存中   2.读或者写文件  3.关闭文件

        打开文件:

        语法:open(file,mode='r',encoding=None)

        file是要打开的文件,类型是字符串,文件的路径可以是绝对路径或者相对路径,建议使用相对路径;mode默认参数(缺省参数),表示的是打开文件的方式,r 表示只读打开,w表示打开写,a表示追加打开即在文件的末尾写入内容;参数encoding表示编码方式,表述文件和二进制如何进行转换

        返回值返回的是 文件对象,后续对文件的操作,都需要这个文件

        写文件:

        向文件写入指定内容

        前提:文件的打开方式是a或者w

        语法:文件对象.write('写入的内容')

        返回值是写入文件的字符数,一般不关注

        读文件:

        将文件中的内容读取出来

        前提:文件的打开方式需要是r

         语法:文件对象.read(n),参数n表示读取多少个字符,一般不写,表示读取全部内容

        返回值:读取到的文件内容,类型是字符串       

        关闭文件:

        将文件占用的资源进行清理,同时会保存文件,文件关闭之后,这个文件对象就不能使用

        语法:文件对象.close()

1.写文件

f=open('a.txt','w',encoding='utf-8')#文件不存在就会直接创建文件,文件存在就会覆盖原文件

f.write('好好学习')

f.close()

open('a.txt','w',encoding='utf-8')

f.write('学习')

f.close()

open('a.txt','w',encoding='utf-8')

f.write('好好学习\n')

f.write('学习')

f.close()

2.读文件

f=open('a.txt','r',encoding='utf-8') #r方式打开,如果文件不存在就会报错

buf=f.read()

print(buf)

f.close()

  使用with open 打开文件

        with open()打开文件的好处:不用自己书写关闭文件的代码,会自动关闭   

        语法:with open(file,mode,encoding='utf-8') as 变量:

                #缩进去读或者写文件

                #缩进中的代码执行结束,出缩进之后,文件会自动关闭

  with open(file,a,encoding='utf-8') as f:

        f.write('好好学习')

#使用a,如果文件不存在,就新建,存在就在末尾追加新内容

按行读取文件:

         with open(file,encoding='utf-8') as f:#没有写code的话,默认传递参数a

                buf=f.readline()

                print(buf)

                print(f.readline) #会读取第二行的内容

                print(f.readline) #会读取第三行的内容

读取所有行:

        with open(file,encoding='utf-8') as f:

                for i in f:

                        print(i)

json文件:

        json文件也是一个文本文件,就可以直接使用read() 和write()方法去操作文件,只是说那个这两个方法不方便,所以对json文件有自己独特的读取和写入方法

        常用在做测试的时候,将测试数据定义为json文件格式,使用代码读取json文件,即读取测试数据,进行传参(参数化)

        json基于文本(是一个文本文件,不能包含图片视频等),独立于语言(不是某个语言特有的,每种编程语言都可以使用)的轻量级(与其他格式相比,占用的大小比较小)的数据交换格式 (后端程序员给的数据,比如json,html,xml)

  json文件的后缀是.json

json中主要的数据类型为对象({}类似python字典)和数组([类似于python中的列表),对象和  数组可以相互嵌套

一个json文件是一个对象或者数组(即json的最外层要么是一个{},要么是一个数组[]

json中的对象是由键值对组成,每个数据直接使用逗号隔开,但是一个数据后边不要写逗号

json中的字符串必须使用双引号

json的书写:

“name”:“小康”,

“age”:true,

“like”:[

“听歌”,

“游戏”,

“睡觉”

],

“adrress”:{

“country”:“中国”,

“city”:“上海”

读取json文件

        导包import json,读打开文件,读文件json.load(文件对象)

        返回的是字典(文件中是对象)或者列表(文件中是数组)

import json

with open('info.json',encoding='utf-8')  as f:

     result=json.load(f)

      print(type(result))

     print(result.get('name'))

     print(result.get('address').get('city')

)

json的写入

        文件对象.write(字符串)不能直接将python的列表和字典 作为参数传递

        想要将python中的数据存为json文件,需要使用json提供的方法,不再使用write

        步骤:1导包 import json,2写方式打开文件3写入json.dump(python中的数据类型,文件对象)

import json

        mylist=[('admin','123456','登录成功'),('root','123456','登录失败')]

with open('info.json','w',encoding='utf-8') as f:

        json.dump(mylist,f,ensure_ascii=Falsep,indent=4)

        json.dump(mylist,f,ensure_ascii=Falsep,indent=2)

33  异常

        程序运行时,如果python解释器遇到一个错误,会停止程序的运行,并且提示一些错误信息,这就是异常

        程序停止执行并且提示错误信息这个动作,抛出异常(raise关键字)

        捕获异常:程序遇到异常,默认动作是终止代码程序的执行,遇到异常之后,可以使用异常捕获,让程序代码继续执行,不会终止运行

语法:

try :

     书写可能发生异常的代码

excep  异常类型1:(只能捕获指定类型的异常,如果不是这个异常,还是会报错)

      发生了异常执行的代码

excep  异常类型n:

      发生了异常执行的代码

示例:

try :

    num=input('请输入数字')

    num=int(num)

     print(num)

except   ValueError:

    print('请输入正确数字')

print('其他代码继续执行。。。')

异常捕获的完整格式:

try :

     书写可能发生异常的代码

excep  异常类型1:

      发生了异常执行的代码

excep   Exception as 变量:

      发生了异常执行的代码

else:

     没有发生异常会执行的代码

finally:

    不管有没有发生异常,都会执行的代码

异常传递:

        在函数嵌套调用过程中,被调用的函数发生异常,如果没有捕获这个异常,就会向外层传递,如果传递到最外层还没捕获,才报错

34 模块和包

        python源代码就是一个模块

        模块中定义好的变量 函数  类 ,都可以让别人使用,同样可以使用别人定义的(好处:别人定义好的不需要我们再次书写,直接使用即可)

        想要使用别人的模块泽东内容工具(变量  类  函数),就必须导入模块 才可以

        我们自己写的代码,想要作为模块使用,代码的名字需要满足标识符的规则(由数字,字母中)

导入语法1:import 模块名     模块名.工具名

导入语法2:from 模块名  import 工具名

导入语法3:from 模块名  import  *表示将模块中所有内容都导入

        对于导入的模块都可以使用 as关键字给其起别名,但一旦起别名了,原来的名字就不能用了,只能使用别名

模块的查找顺序:

        在导入模块的时候,会先在当前目录查找模块,如果找到就直接使用,如果没找到就回去系统的目录中进行查找,找到则直接使用,没找到就报错

需注意,定义代码文件的时候,我们的代码名字不能和我们要导入的模块名字相同

_name_的作用

        每个代码文件都是一个模块,在导入模块的时候,会执行模块中的代码

        _name_变量是python解释器自动维护的变量,如果代码是直接运行,值是“_main_“,如果代码是被导入执行,值是  模块名 (指代码文件名)

        在python中,包是一个目录,只不过在这个目录存在一个文件 init.py,将功能相近或者相似的代码放在一起

        在python中使用的时候,不需要区分是包还是模块,使用方法是一样的

        import 包名或者alt➕回车

35   unittest

        框架:为解决一类事情的功能集合

        unittest框架是python自带的一个单元测试框架,用它来做单元测试

        自带的框架:不需要单独安装,只需安装了python就可以使用

        第三方框架:想要使用,需要先安装后使用pytest

        单元测试框架,主要用来做单元测试,一般单元测试是开发做的,对于测试来说,unittest框架的作用是  自动化脚本(用例执行)执行框架,使用unittest框架来 管理 运行 多个测试用例的

使用unittset框架的原因:

        能够组织多个用例去执行

        提供丰富的断言方法(让程序代码代替人工自动的判断预期结果和实际结果是否相符)

        能够生成测试报告

unittest核心要素(unittest的组成):

        testCase(测试用例),注意这个测试用例是unittest框架组成部分,不是手工和自动化中我们所说的用例(test  case),主要作用是每个testcase都是一个代码文件,这个代码文件中,来书写真正的测试用例

        TestSuite(测试套件),用来管理  组装(打包)多个TestCase

        TestRunner(测试执行),用来执行TestSuite

        TestLoader(测试加载),用来TestSuite的功能补充,管理 组装(打包)多个TestCase的

        Fixtrue(测试夹具),书写在TestCase代码中,是一个代码结构,可以在每个方法执行前后都执行的内容,每个用例重复的代码可以写在Fixture代码结构中,只写一遍,但每次用例方法的执行,都会执行Fixture中的代码

TestCase测试用例的书写

        是一个代码文件,在代码文件中来书写真正的用例代码

        代码文件的名字必须按照标识符的规则来书写(可以将代码的作用在文件开头进行标注)

步骤:

1.导包(unittest)

2.自定义测试类,需要继承unittest模块中的TestCase即可

3.在测试类中书写测试方法,即用例代码(目前没有真正的用例代码,使用print代替),书写要求是测试方法必须以test_开头(本质是以test开头))

4.执行用例,将光标放在类名后边运行,会执行类中所有的测试方法,光标放在方法名后边运行,会执行方法中所有的测试方法,

import unittest

class TestDemo(unittest.TestCase):

    def test_method1(self):

        print('测试方法1')

    def test_method2(self):

        print('测试方法2')

 

 

代码书写常见的错误:

1.代码文件命名不规范

比如代码文件名字以数字开头;代码文件名字中有空格;代码文件名字有中文;有特殊的符号(数字字母下划线以外的字符)

2.代码运行没有结果

右键运行没有unittests for提示,出现的问题

解决方案一:首先新建代码文件,将原来的代码复制进去新文件 

解决方案二:删除已有的运行方式(点击右上角倒三角,然后点击 edit configurations,接着点击弹窗左上角的减号)

3.没有找到用例

测试方法中不是以test_开头或者单词写错了

TestSuilte和TestRunner的书写

步骤:

1.导包(unittest

2.实例化(创建对象)套件对象)

3.使用套件对象添加实例方法,建议测试类名和方法名直接去复制,不要手写

4.实例化运行对象

5.使用运行对象去执行套件对象

假设我们写了两个测试类TestDemo1和TestDemo2,每个类中都有两个测试方法test_method1和test_method2

方法一

import unittest

suite=unittest.TestSuite()

suite.addTest(TestDemo1('test_method1))

suite.addTest(TestDemo1('test_method2))

suite.addTest(TestDemo2('test_method1))

suite.addTest(TestDemo2('test_method2))

runner=unittest.TextTestRunner()

runner.run(suite)

方法二:将一个类中所有方法添加

import unittest

suite=unittest.TestSuite()

suite.addTest(unittest.makeSuite(TestDemo1))

suite.addTest(unittest.makeSuite(TestDemo2))

runner=unittest.TextTestRunner()

runner.run(suite)

 

查看结果的方法:

        结果的   .   表示一个用例通过(如果四个用例通过就四个  .   ,以此类推),F表示用例不通过,E表示用例代码有问题

TestLoader使用

步骤:

1.导包(unittest

2.实例化测试加载对象并添加用例(得到的是suite对象)

3.实例化运行对象

4.使用运行对象去执行套件对象

        TestLoader里的代码变成下面这样也要认得出来 

# 导包
import unittest# 实例化加载对象并添加用例
# unittest.TestLoader().discover('用例所在路径','用例的代码文件名')
# 用例所在路径建议使用相对路径,用例的代码文件名可以使用 *(任意多个字符)  通配符
# suite = unittest.TestLoader().discover('./', 'TestA*.py')
suite = unittest.defaultTestLoader.discover('./', 'TestA*.py')
# 实例化运行对象
runner = unittest.TextTestRunner()
# 执行
runner.run(suite)

Fixture:

        Fixture是一个概述,对一个测试用例环境的初始化和销毁就是一个Fixture

        Fixture控制级别:方法级别,类级别,模块级别

        方法级别:在每个测试方法(用例代码)执行前后都会自动调用的结构

        类级别:在每个测试类中所有方法执行前后,都会自动调用的结构(在整个类中 执行之前执行之后各一次,类级别的fixture 是一个类方法

        模块级别:在每个代码文件执行前后执行的代码结构

        方法级别和类级别 的前后方法 ,不需要同时出现,按需自行选择使用

        

#方法级别
# 方法执行之前
def setup(self):# 每个测试方法之前执行pass# 用例代码放在这边def teardown(self):# 每个测试方法之后都会执行pass
#类级别
#类中所有方法之前
@classmethod
def setupClass(cls):pass#类中所有方法之后
@classmethod
def teardownClass(cls):pass
#模块级别
# 模块级别需要写在类的外边直接定义函数即可
# 代码文件之前
def setupModule():pass
# 代码文件之后
def teardownModule():pass

案例:

        1,打开浏览器(整个测试过程中就打开一次浏览器)  类级别

        2,输入网址(每个测试方法都需要一次)  方法级别

        3,输入用户名和密码验证码点击登录 (不同的测试数据)  测试方法

        4,关闭当前页面(每个测试方法都需要一次) 方法级别

        5,关闭浏览器(整个测试过程就关闭一次浏览器)  类级别

        ----

        1,打开浏览器(整个测试过程中就打开一次浏览器)  类级别

        2,输入网址(每个测试方法都需要一次)  方法级别

        3,输入用户名和密码验证码点击登录 (不同的测试数据)  测试方法

        4,关闭当前页面(每个测试方法都需要一次) 方法级别

        

        2,输入网址(每个测试方法都需要一次)  方法级别

        3,输入用户名和密码验证码点击登录 (不同的测试数据)  测试方法

        4,关闭当前页面(每个测试方法都需要一次) 方法级别

        

        2,输入网址(每个测试方法都需要一次)  方法级别

        3,输入用户名和密码验证码点击登录 (不同的测试数据)  测试方法

        4,关闭当前页面(每个测试方法都需要一次) 方法级别

        

        5,关闭浏览器(整个测试过程就关闭一次浏览器)  类级别

 

import unittestclass TestLogin(unittest.TestCase):def setUp(self):# "每个测试方法执行之前都会先调用的方法"print('输入网址...')def tearDown(self) -> None:# "每个测试方法执行之后都会先调用的方法"print('关闭当前页面...')@classmethoddef setUpClass(cls) -> None:print('1.打开浏览器')@classmethoddef tearDownClass(cls) -> None:print('5.关闭浏览器')def test_1(self):print('输入正确的用户名密码验证码,点击登录1')def test_2(self):print('输入正确的用户名密码验证码,点击登录2')

 36 断言

        让程序代替人工自动的判断预期结果和实际结果是否相符

        断言的结果有两种:true(表示用例通过),False(代码抛出异常,用例不通过)

        常用断言语法    解释
assertEqual(预期结果a, 实际结果b)     判断a==b
assertNotEqual(a, b)    判断a!=b
assertTrue(x)    bool(x) is True
assertFalse(x)    bool(x) is False
assertIs(a, b)    a is b
assertIsNot(a, b)     a is not b
assertIsNone(x)     x is None
assertIsNotNone(x)    x is not None
assertIn(预期结果a,实际结果 b)     a in b预期结果是否包含在实际结果中
assertNotIn(a, b)    a not in b
assertIsInstance(a, b)    isinstance(a, b) 
assertNotIsInstance(a, b)     not isinstance(a, b)

例子:

        asserIn('admin','admin') #包含

        asserIn('admin','adminnnnnn') #包含

         asserIn('admin','aaaaaaadmin') #包含

        asserIn('admin','aaaaadmimnnnnn') #包含

        asserIn('admin','addddmin') #不包含

 37 参数化

        在测试方法中,使用 变量 开替代具体的测试数据,然后使用传参的方法将测试数据传递给方法的变量

        好处:相似的代码不需要多次书写

        工作中的场景:测试数据一般放在json文件中,使用代码读取json文件,提取我们想要的数据

        unittest 框架本身不支持参数化,但是可以通过安装unittest拓展插件parameterized来实现

        安装语句:pip install parameterized

        验证:pip list可以查看到parameterized

参数化代码:

        1.导包

        2.定义测试类

        3.书写测试方法(用到的测试数据使用变量替代)

        4.组织测试数据      

import unittest

import Add(要测试的自己写的类,里面有个自己写的方法add)

data[

(2,3,5),(1,2,3),(8,9,17)

]

class Test(unittest.TestCase):

        @parameterized.expand(data)

        def testAdd(self,num1,num2,except)

                self.assertEqual( except,Add.add(num1,num2))

        如果数据在data.json文件里,代码可以变更为 

import unittest

import Add(要测试的自己写的类,里面有个自己写的方法add)

def build_data():

        with open('data.json'),encoding='utf-8') as f:

                result=json,load(f)

                data=[]

                for i in result:

                        data.appned(i.get('num1'),i.get('num2'))

        return data

class Test(unittest.TestCase):

        @parameterized.expand(data)

        def testAdd(self,num1,num2,except)

                self.assertEqual( except,Add.add(num1,num2))

常见错误

1.no such file for directory :'xxxxx'

查看是否文件名写错了
2.'NoneType' object is not iterable

数据是空的

跳过:

        对于一些未完成或者不满足测试条件的测试函数和测试类,可以执行跳过

        使用方式:@unittest.skip('跳过原因')可以直接将测试函数标记为跳过;@unittest.skipIf(condition,reason)可以根据条件判断测试函数是否跳过 ;注意上述两种方法要写在TestCase里

38 测试报告

         自带的测试报告:只有单独运行TestCase的代码,才会生成测试报告

        生成第三方的测试报告:HTMLTestRunner是一个第三方库,用来执行测试用例并生成HTML格式的测试报告,需注意,下载的python文件要与python兼容(有的版本只支持python2.x)

1.获取第三方的 测试运行类模块,将其放在代码的目录中

2.导包unittest

import unittest

from HTMLTestRunner  import HTMLTestRunner

3.使用 套件对象,加载对象 去添加用例方法

suite = unittest.defaultTestLoader.discover('.',Add.py')

4.实例化 第三方的运行对象 并运行 套件对象

#HTMLTestRunner()

#stream=sys.stdout,必填,测试报告的文件对象(open),注意要使用wb打开

#verbosity=1,可选,报告的详细程度 ,1 简略 2详细

#title=None可选,测试报告的标题

#description=None 可选,描述信息,python版本,pycharm版本

#file='report.html'  报告的后缀是.html

file ='report.html'

with open(file,'wb') as f:

        #runner =HTMLTestRunner(f) #运行对象

        runner=HTMLTestRunner(f,2,'测试报告','Python') #运行对象

        #运行对象执行套件.要写在with的缩进中

       runner.run(suite)

 中文化测试报告:

import unittest 

from HTMLTestRunneCNr  import HTMLTestReportCN

suite = unittest.defaultTestLoader.discover('.',Add.py')

with open('report.html','wb') as f:

        runner =HTMLTestReportCN(f) #运行对象

       runner.run(suite)

 1.组织用例文件(TestCase里边),书写参数化,书写断言.书写Fixture,书写 跳过,如果单个测试文件,直接运行,得到测试报告,如果多个测试文件,需要组装运行生成测试报告

2.使用 套件对象组装,加载对象组装

3.运行对象 运行

3.1运行对象=第三方的运行类(文件对象(打开文件需要使用wb方式))

3.2运行对象.run(套件对象)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/281683.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1236 - 二分查找

代码 #include<bits/stdc.h> using namespace std; int a[1100000]; int main() {int n,x,l,r,p,mid,i;cin>>n;for(i1;i<n;i)cin>>a[i];cin>>x;l1;rn;p-1;while(l<r){mid(rl)/2;if(a[mid]x){pmid;break;}else if(x<a[mid]) rmid-1;else if(x…

数据结构——循环队列的实现

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

UDS协议从入门到入坑分享

** 一、概念先行 ** UDS&#xff08;全称&#xff1a;UnifiedDiagnostic Services&#xff09;&#xff0c;诊断协议是在汽车电子ECU环境下的一种诊断通信协议&#xff0c;在ISO 14229中规定。 目前市面上的新车都具有用于车外诊断的诊断接口&#xff0c;这使得我们可以用电脑…

ArcGIS添加天地图底图服务

目录 一、注册天地图官网、申请Key 二、ArcGis配置和使用 1、配置 2、使用 三、其他方法 一、注册天地图官网、申请Key 进入官网&#xff0c;并注册账号。 地址&#xff1a;国家地理信息公共服务平台 天地图 (tianditu.gov.cn) 点击地图API&#xff0c;申请Key。 注意&am…

【Java Web基础】一些网页设计基础(四)

文章目录 1. 做Tab切换2. 下面的内容展示——Card样式3. 采供分类&#xff0c;分类用面包屑导航做4. 出名企业展示&#xff0c;就是普通的图片5. 用热门商品类似的panel做一个农博会展览 1. 做Tab切换 使用BootStrap提供的样式&#xff1a; <ul class"nav nav-tabs&q…

Python基础学习笔记(一)

Python简介 Python 语言是一种跨平台、开源、免费、解释型、面向对象、动态数据类型的高级程序设计语言。早期版本的 Python 被称作是 Python1&#xff1b;Python2 最后一个版本是 2.7&#xff1b;Python3 是目前最活跃的版 本&#xff0c;基本上新开发的 Python 代码都会支持…

视频批量爬虫下载工具|可导出视频分享链接|抖音视频提取软件

便捷的视频批量爬虫软件操作指南 抖音视频下载界面图解 主要功能&#xff1a; 关键词批量提取视频和单独视频提取&#xff0c;提取后下载功能。 功能解析&#xff1a; 1. 关键词批量采集视频的解析 对特定关键词进行搜索和视频提取&#xff0c;例如输入“汽车配件”&#x…

C#探索之路基础篇(1):编程中面向过程、数据、对象的概念辨析

文章目录 C#探索之路基础篇(1)&#xff1a;编程中面向过程、数据、对象的概念辨析1 面向过程编程1.1 概念1.2 示例代码&#xff1a;1.3 使用范围与时机&#xff1a;1.4 注意事项&#xff1a;1.5 通俗讲法 2 面向对象编程2.1 概念2.2 示例代码2.3 使用范围2.4 注意事项2.5 通俗讲…

【吾爱破解】Android初级题(二)的解题思路 _

拿到apk&#xff0c;我们模拟器打开看一下 好好&#xff0c;抽卡模拟器是吧&#x1f600; jadx反编译看一下源码 找到生成flag的地方&#xff0c;大概逻辑就是 java signatureArr getPackageManager().getPackageInfo(getPackageName(), 64).signaturesfor (int i 0; i &l…

2024.3.22 使用nginx在window下运行前端页面

2024.3.22 使用nginx在window下运行前端页面 使用nginx可以在本地运行前端程序&#xff0c;解决本地前后端程序跨域问题&#xff0c;是个前期编程及测试的好办法。 nginx下载 直接在官网下载 本次选择了1.24版本&#xff08;stable version&#xff09; nginx安装 解压后…

公司系统中了.rmallox勒索病毒如何恢复数据?

早晨上班时刻&#xff1a; 当阳光逐渐洒满大地&#xff0c;城市的喧嚣开始涌动&#xff0c;某公司的员工们纷纷踏入办公大楼&#xff0c;准备开始新的一天的工作。他们像往常一样打开电脑&#xff0c;准备接收邮件、查看日程、浏览项目进展。 病毒悄然发作&#xff1a; 就在员…

【计算机】——51单片机

单片机是一种内部包含CPU、存储器和输入/输出接口等电路的集成电路&#xff08;IC芯片&#xff09; 单片机是单片微型计算机&#xff08;Single Chip Microcomputer&#xff09;的简称&#xff0c;用于控制领域&#xff0c;所以又称为微型控制器&#xff08;Microcontroller U…

Eclipse For ABAP:安装依赖报错

1.安装好Eclipse后需要添加依赖,这里的地址: https://tools.hana.ondemand.com/latest 全部勾选等待安装结束; 重启后报错:ABAP communication layer is not configured properly. This might be caused by missing Microsoft Visual C++ 2013 (x64) Runtime DLLs. Consu…

Http中Host,Referer,Origin和Access-Control-Allow-Origin

Http中Host&#xff0c;Referer&#xff0c;Origin和Access-Control-Allow-Origin 文章目录 Http中Host&#xff0c;Referer&#xff0c;Origin和Access-Control-Allow-OriginHost定义特性作用 Referer定义特性作用 Origin定义特性作用 Access-Control-Allow-Origin定义特性作用…

【Arxml专题】-29-使用Cantools将CAN Matrix Arxml自动生成C语言代码

目录 1 安装Python和Cantools 1.1 查看Python已安装的Package包 1.2 在Python中安装Cantools插件包 1.3 获取更多Cantools工具的更新动态 2 CAN Matrix Arxml自动生成C语言代码 2.1 批处理文件CAN_Matrix_Arxml_To_C.bat内容说明 2.2 CAN Matrix Arxml文件要求 2.3 如何…

ideaSSM 人才引进管理系统bootstrap开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 idea 开发 SSM 人才引进管理系统是一套完善的信息管理系统&#xff0c;结合SSM框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff…

复旦大学MBA首场公开课:独具特色的培养体系和招生政策

3月2日&#xff0c;2025年入学复旦MBA首场公开课暨招生政策发布会圆满收官。心怀梦想、力求突破的青年精英们相聚于复旦&#xff0c;共同聆听一场精彩纷呈的知识盛宴&#xff0c;了解复旦MBA独具特色的培养体系和招生政策&#xff0c;在明媚的春光中迈向崭新的未来。      …

Svg Flow Editor 原生svg流程图编辑器(三)

系列文章 Svg Flow Editor 原生svg流程图编辑器&#xff08;一&#xff09; Svg Flow Editor 原生svg流程图编辑器&#xff08;二&#xff09; Svg Flow Editor 原生svg流程图编辑器&#xff08;三&#xff09; 实现对齐辅助线 在 logicFlow 中&#xff0c;辅助线的实现是通…

易快报与国贸SAP秒同步,数据同步不再是难题!

客户介绍 某国际贸易有限公司是一家在中国享有广泛声誉的国际贸易企业&#xff0c;专注于促进中美两国之间的经贸合作与交流。公司凭借深厚的行业经验和专业的团队&#xff0c;致力于为客户提供高效、可靠的贸易服务&#xff0c;涵盖了多个领域&#xff0c;包括商品进出口、供…

MAC本安装telnet

Linux运维工具-ywtool 目录 1.打开终端1.先安装brew命令2.写入环境变量4.安装telnet 1.打开终端 访达 - 应用程序(左侧) - 实用工具(右侧) - 终端 #注意:登入终端用普通用户,不要用MAC的root用户1.先安装brew命令 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/H…