python学习

简介

python只是一个变成语言,工作中需要结合其他工具使用

python + selenium web   自动化(功能测试转换为代码)

python + appium  移动端(手机APP)自动化

python + requests 接口

print函数

print()是python自带的函数,作用在控制台中输出,括号中的内容后续看到这个函数就是输出打印数据的,或者想要在控制台中显示某个内容,就要使用print()函数

print()函数中是什么内容,就会显示什么,可以是“”也可以是‘’

注释

python中的注释有俩种,单行注释和多行注释

单行注释

使用井号和空格进行注释(单独y一个#也可以)

快捷方式 ctrl /

多行注释

多行注注释中的内容 可以换行书写

多行注可以使用3对双引号或者3对单引号,被三对引号包括的内容就是注释的内容

三对引号的注释一般写到一开始处,或者文档注释处(函数)

代码中的波浪线和PEP8

红色:红色是代码的错误,必须把错误解决才能执行

灰色:不会影响代码的正常执行

PEP8:python代码的书写规范,如果不按照书写规范就会出现灰色波浪线 ,建议代码书写按照PEP8的规范书写

1.书写代码时注意用PEP8的规范

2.可以在书写完成后,使用快捷键Ctrl Alt L 来按照PEP8的规范自动格式化代码

绿色:不影响代码的正常运行,认为你书写的内容不是一个单词

变量

作用:是用来存贮数据的(在程序代码中出现的数据,想要保存下来使用,就必须使用变量)如:测试数据,用户名,密码,验证码

变量注意使用:变量必须先定义(保存数据)后使用(取出数据)

定义变量

变量名=数据值  # 将数据值保存到变量中

使用变量

变量定义后,想要使用变量中的数据,直接使用变量名即可

name='张三'
print(name)# 张三

使用变量打印是不需要引号

name='张三'
print('name') #name

添加引号后就会输出引号中的内容

变量名的命名规则

起名的规范,标识符的规则

1.必须由字母数字下划线组成,并且不能以数字开头

2.不能用书python中的关键字

3.区分大小写

4.建议性命名

!驼峰命名法

1.大驼峰:每个单词的首字母大写  MyName  小驼峰:第一个单词的首字母 小写,其余单词的首字母大写myNAME

下划线连接my_name

python 中的变量定义使用的是下划线连接

见名知意

数据类型

整形(int),就是整数,即不带小数点的数

浮点型(float),就是小数

布尔类型(bool),只有两个值

1.真(True) 1  2.假(False)0,非0即真

True跟False都是python中的关键字,注意大小写不要写错了

复数类型3+4i,不会用的

非数字类型

字符串:(str)使用引号引起来的就是字符串

列表(list)[1,2,1]

原组(tuple)(1,2,4,4)

字典(dict){‘name’:‘小明,‘age’:15}

type()函数

可以获取变量的数据类型

type(变量)

想要将这个变量的类型在控制台显示,需要使用print输出

print(type(变量))

输入

获取用户使用键盘录入的内容

使用的函数是input()

变量=input(‘提示的信息’)

数据类型转换

输出

输出使用的是print()函数,作用,将程序中的数据或结果打印到控制台(屏幕)

print(‘hello world’)

name=‘小明’

print(name)

age=18

print(name,age)#使用逗号输出多个内容

格式化输出

在字符串中指定的位置,输出变量中存储的值,

1.在需要使用变量的地方,使用特殊符号站位

2.使用变量填充占位的数据

%格式化输出占位符号

%d 占位,填充 整型数据digit

%f  占位,填充 浮点型数据float

%s 占位, 填充 字符串数据 string

age = 18
height = 18
name = '小明'
及格率 = 90
print('他的名字为: %s,身高 %.1f,年龄%d' % (name, height, age))
print('他的及格率为: %d%%' %及格率 )

 # 当需要输出一个%时,需要两个%

F-string(f字符串的格式化方法

1.需要在字符串前面加f或F

2.占位符统一为{}

3.需要填充的变量,写在{}中

运算符

算数运算符

字符串的格式化补充

字符串.format()、

1.在需要使用 变量的地方使用{}占位

2.‘{},{}....’.format(变量,变量......)

逻辑运算符

and 一假则假   or 一真则真     not 取反

赋值运算符

=,将等号右边的值保存到左边的变量中

运算符优先级,不需要刻意去记,()刻意改变优先级

判断

if   else  elif

在代码中有判断语句,代码不会全部执行,有一部分不会执行

if的基本结构

如果的条件成立,会执行的代码,会做的事

基本语法

if 判断条件:

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

定格书写,没有缩进的代码,与if无关,不管条件是否成立,都会执行

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

#2.判断条件后面需要一个:

#3.冒号之后,回车,代码需要缩进,在pthcharm中自动进行缩进,一般是4个空格或者一个tab健

#4.所有在if代码块下方的缩进中书写的代码,属于if语句的代码块,判断为true时执行

#5.if中的代码块,要么都执行,要么都不执行

#6.if代码块结束之后,代码要定格书写(不再有缩进),表示是和if无关的代码

if else

基本语法

if 判断条件:

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

else:

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

# 1.else 是关键字,后面需要冒号

2.冒号回车后同样需要缩进

3.处于else 代码下方缩进中的内容,属于else 的代码块

4.if 和 else 的代码块,只会执行其中的一个

5.else 需要配合if 使用

DEBUG

debug 在代码出现问题错误(bug),可以使用debug来调试代码,查找错误,我们使用debug主要用来查看代码执行步骤

1.打断点

在pychar中,代码和行号之间进行点击,出现小红点及打断点

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

随机出拳

案例中需要电脑随机出拳,及随机出1,2,3

在python中想要随机获得整数数字可以使用如下方法

1.导入随机数工具包

import random

2.使用工具包中的工具产生指定范围的数字

random.randint(a,b) #产生【a,b】之间的随机数,包含a,b

import random #这行代码一般来说放在第一行

循环

语法

1.设置循环的初始条件(计数器)

2.书写循环的判断条件

while 判断条件:

        #需要重复的代码

        #改变循环的初始条件

死循环

while True:

        重复执行的代码

        if 判断条件:

                break #是python的关键字,直接跳出循环

for循环

for循环可以让指定的代码重复执行(循环)

for循环可以遍历容器中的数据(

        遍历:从容器中把数据一个一个取出

        容器:可以简单理解为盒子,盒子中可以存放很多的数据(字符串str,列表list,元组tuple,字典dict)

for循环可以称为for遍历

语法:

for 变量名 in 容器:

        重复执行的代码

for做指定次数的循环

for 变量 in range(n):

        重复执行的代码

1.in range()是python中的函数,作用可以生成[0,n)之间的整数,不包含n的,一个有n个数字,所以循环几次

2.想让for循环几次,n就写几

3.第一次取的值是0,最后一次是n-1

rang()变形

for 变量  in range(a,b):

        重复的代码

# 作用是生成[a,b)之间的整数

break 和 continue

break和continue是python中的两个关键字,只能在循环中使用

break:终止循环,即代码执行遇到break,循环不在执行,立即结束

continue:跳过本次循环,即遇到代码

容器

容器:数据序列,也是高级数据类型,也是python中的数据类型

容器中可以放多个数据。

字符串

字符串是容器,因为字符串中包含多个字符

使用引号(单引号,双引号,引号)引起来的内容就是字符串

下标

下标(索引):就是指字符在字符串中的位置编号,这个编号就是下标

这个编号一般来说都是从左到右进行编号的,从0开始(python中支持负数下标,从右到左进行编号,从-1开始)

语法:

字符串[下标] #获取指定位置的字符

获取字符串的长度    len(字符)

切片

切片:可以获取字符串中多个字符(多个字符的下标都是有规律的,等差数列)

语法:

字符串[strar:end:step]

1.strar:是开始位置的下标,end是结束位置的下标(注意:不能取到这个位置的字符,step步长,等差数列的差值,所相邻字符下标之间的插值,默认是1,可以不写)

字符串的查找

用法:

字符串.find(sub_str,strar,end)

作用:在字符串中查找是否存在sub_str 这样的字符串

sub_str:要查找小的字符串

strar:开始位置,从哪个下标位置开始查找。一般不写,默认为0

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

返回(代码执行之后会得到什么,如果有返回,就可以使用变量保存):

        1.如何在字符串中找到了sub_str,返回sub_str第一次出现的正数下标(sub_str 中第一个字符在大字符串中的下标)

        2.如果没有找到,返回-1

字符串的替换

用法

字符串.replace(old_str,new_str,count)#讲字符串中old_str替换为new_str

old_str:被替换的内容

new_str:替换的内容

count:替换个数,不写就全部替换

字符串的拆分

字符串.split(sep,max_split)#将字符串按照sep进行分割(拆分)

sep:字符串按照什么进行拆分,默认是空白字符(空格,换行,tab)

max_split,分割次数,一般不写,全部分割

返回:将一个字符串拆分为多个,存到列表中

注意:如果sep不写,想要指定分割次数则按照如下方式使用

字符串.split(max_split=n) #n是次数

字符串的链接join

字符串.join(列表)#括号中的内容主要是列表,可以是其他容器

#作用:将字符串插入到列表中每相邻的两个数据之间,组成一个新的字符串

- 列表中的数据使用 用逗号分开

- 注意点:列表中的数据必须是字符串,否则回报错

列表

列表list ,是使用最多的一种容器(数据类型)

列表中可以存放多种数据类型,每个数据类型使用逗号隔开

列表中可以存放任意类型的数据

列表支持下标和切片操作

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

在字符串中使用find方法查找下标的,不存在返回的是-1

在列表中没有find方法,想要查找数据的下标,使用index()的方法

列表.index(数据,start,end)使用find方法一样,在字符串中也有inde()方法

区别:返回,index()方法,找到返回第一次出现的下标,没有找到代码直接报错

查找-判断是否存在

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

数据   in 容器      #如果存在返回Ture ,如果不存在返回False

查找-统计出现的次数

统计出现的次数,使用的是count()方法

列表.count(数据)   #返回 数据出现的次数

添加数据的方法

--尾部添加(最常用)

列表.append(数据)  #将数据添加到列表的尾部

返回:返回None(关键字,空),一般就不再使用变量来保存返回的内容

想要查看添加后的列表,需要打印的是列表

--指定下标位置添加

列表.insert(下标,数据)    #在指定的下标添加数据,如果指定的位置有数据则源数据会后移

返回:返回None(关键字,空),一般就不再使用变量来保存返回的内容

想要查看添加后的列表,需要打印的是列表

--列表合并

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

列表修改

lis1[下标] =要修改的内容

列表删除

在列表中删除中间的数据,则后面的数据像前面移动

--根据下标删除            

列表.pop(下标)#删除指定下标位置对应的数据        

1.下标不写,默认删除最后一个数据

2.书写存在的下标,删除对应下标位置的数据

返回:返回删除的数据    

--根据数据值删除

列表.remove(数据值)# 根据数据值删除

返回None

如果数据不存在则会报错

清空数据

列表.clear

列表的反转

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

列表中 反转和倒置:

1.列表[::-1]使用切片的方法将列表倒置,源列表不发生改变

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

列表的复制

将列表中的数据复制一份,给到新的列表

1.使用切片

变量=列表[:]

2.使用copy方法

变量=列表.copy()

列表的排序

列表的排序,一般来说都是对数字进行排序的

列表.sort()#按照升序排序,从小到大

返回值none直接修改原列表

列表.sort(reverse=Ture)  #降序排序,从大到小

返回值none    直接修改原列表

列表嵌套

列表中的内容还是列表

使用下标来确定获取的是什么类型的数据,然后确定可以继续进行的操作

元组

元组:tuple,元组的特点和列表非常相似

1.元组可以存放任意类型的数据

2.元组可以存放任意多个数据

区别:

1.元组中的数据内容不能改变,列表中可以改变

2.元组是用(),列表使用[ ]

应用:在函数传参和返回值时使用,保证数据不会改变

定义

1.使用 类实例化方式

2.直接使用()方式

常用方法

由于元组中数据不能改变,只能进行查看

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

2.在元组中存在index 方法,查找下标,如果不存在。则会报错

3.在元组中存在count 方法,统计数据出现的次数

4.在元组中可以使 用 in 操作,判断数据是否存在

5.len()统计个数

以上方法和列表中的使用是一样的

列表转换成元组与字符串转换成元组例:

注:元组中有一个数据时一定要加逗号    tuple=(1,)

字典

1.字典dict,字典中的数据有键(key)值(value)对组成(键表示数据的名字,值就是具体的数据)

2.在字典中一组键值对对一个数据,多个键值对之间使用,逗号隔开变量={kye:value,key:value...}

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

增加和修改操作

语法

字典[键]=值

如果数据已经存在,则就是修改

如果没有数据存在,就是增加

字典操作实例:

删除

删除指定键值对

del 字典[键]

清空

字典.clear()

 

查询-根据键获取对应的值

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

-使用字典[键]

字典[键]

1.如果键存在。则返回键对应的数据值

2.如果键不存在,会报错

-使用字典.get(键)

字典.get(键,数据值)

1.数据值一般不写,默认为none

返回:

1.如果键存在。则返回键对应的数据值

2.如果键不存在,返回括号中书写的数据值(None)

一般建议使用get方法

mydict = {'name': 'liming', 'sex': '男', 'like': ['抽烟', '喝酒', '烫头']}
print(mydict.get('name')) #liming
print(mydict['like'])     #['抽烟', '喝酒', '烫头']
print(mydict['like'][2])  #获取like中的  第三个数据
字典的遍历

for 变量  in 字典:

        print(变量)  #变量就是字典的kye 键

for 变量 in 字典.keys(): #字典.kyes()可以获取字典中所有的键、

        print(变量)

对字典的值进行遍历

for 变量 in 字典.values(): #字典.values ()可以获取字典中所有的值

        print(变量)

对字典的键值对进行遍历

mydict = {'name': 'liming', 'sex': '男', 'like': ['抽烟', '喝酒', '烫头']}
for i in mydict:
    print(i)  # sex like name 
for n in mydict.keys():
    print(n)  # sex like liming
for v in mydict.values():
    print(v)  # liming 男 ['抽烟', '喝酒', '烫头']
for x, z in mydict.items():  #name liming 
    print(x, z)              #sex 男
                            #like ['抽烟', '喝酒', '烫头']

容器的部分总结

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

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

str = 'like'
str2 = 'me'
str3 = str + str2
print(str3) #likeme
list1=[1,6,6]+[5,9,4,6]
print(list1) #[1, 6, 6, 5, 9, 4, 6]
tuple1=('as',1)+(2,6)
print(tuple1) #('as', 1, 2, 6)
str5='like'*3
print(str5) #likelikelike
list6=[1,3]*6
print(list6) #[1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3]
tuple7=('aas',6,56,798)*2
print(tuple7)  #('aas', 6, 56, 798, 'aas', 6, 56, 798)

函数

函数,就是把具有独立功能模块的代码块,组织为一个小模块,在需要的时候调用

函数,通俗理解,将多行代码写在一块,起个名字,在需要这多行代码的时候,可以直接使用这个名字来代替

函数好处:减少代码的冗余,提高程序的编写效率

函数定义

1.将多行代码放在一起,起名字的过程

2.函数必须先定义后调用

语法

def 函数名():

        函数中的代码

        函数中的代码

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

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

#3.处于def 缩进中的代码成为函数体

4.函数定义的时候,函数体重的代码不会执行,在调用的时候才会去执行

函数定义技巧:在前期,书写不熟练的时候,1.可以先不管 函数,先把功能写出来2.给多行代码起名字3.选中多行代码,使用tab缩进

函数的调用

1.使用函数的过程,称为函数的调用

语法

-函数名()

  1.函数调用的时候会执行函数体中的代码

2.函数调用的时候,要写在函数体外面

文档注释

文档注释,也是注释,作用:主要告诉其他程序员这个函数是干什么的

在函数名下方使用三个双引号

查看:在调用的时候,将光标放到函数名上,使用快捷键ctral+q(Windows)、

def sayhello():
    """三个hello"""
    print('hello 1')
    print('hello 2')
    print('hello 3')
sayhello()

列表去重

列表去重:列表中存在多个数据,需求,去除列表中重复的数据

方式1. 思路

遍历原列表中的数据判断在新列表中是否存在,如果不存在,不管,如果不存在放入新列表中

遍历:for 循环实现

判断是否存在:可以使用in

存入数据append()

方法2.:

在python中还有一种数据类型(容器),称为集合(set)

特点:集合中不能有重复的数据(如果有重复的数据会自动去重)

1.使用set()类型转换将列表转换为集合类型

2.使用list()类型转换为列表类型

缺点:不能保证数据在源列表出现的数据(一般来说,也一般不考虑)

list1=[1,1,2,3,4,6,1,3,2,1,]
new = []
for i in list1:
    if i not in new :
        new.append(i)
print(new)\

函数基础

函数的参数

含义:在函数定义的时候,使用变量代替具体的数据值,在函数调用的时候,传递具体的数据值        

好处:让函数更加通用,能够解决一类问题,而不是单纯的一个

函数的返回值,可以理解为是函数整体执行的结果是什么

print ---》None

input()--》键盘输入的内容

type()---》类型

len()--》数据的长度(元素的个数)

在函数中想要将一个数据作为返回值返回,需要使用return关键字(只能在函数中使用)

作用:

        1.将数据值作为返回值返回

        2.函数代码遇到retrun,会结束函数的执行

返回值说明

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

        pass  #代码中没有return

def 函数名():

        return     #rreturn后面没有返回值,返回None

def 函数名():

        return XX   #return返回xx

变量进阶 

在这部分 我们了解python 底层是如何处理数据的

变量的引用

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

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

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

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

5.可以使用id()函数可以查看变量中保存数据所在的内存地址,如果两个变量的id()获取的引用地址一样,即代表,变量引用了同一个数据,是统一一个数据

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

可变类型和不可变类型

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

可变和不可变指:数据所在的内存是否允许修改,允许修改就是可变类型,不允许修改就是不可变类型

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

不可变类型:int  float bool str tupe

两个数据交换

python 特有方法

a=10
b=20
a,b=b,a
print(a,b)

组包和拆包

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

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

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

a=10
b=20
c=a,b   #组包
print(type(c), c)  #<class 'tuple'> (10, 20)
a,b=c   #拆包   
print(a, b)      #10 20

局部 变量和全局变量

变量:根据变量定义位置,可以将变量分为局部变量和全局变量

局部变量

局部变量:在函数内部定义的变量,称为局部变量

特点:
1.局部变量只能在当前函数内部使用,不能再 其他函数和函数外部使用

2.在不同函数中,可以定义名字相同的局部变量,两者之间没有关系

全局变量     

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

特点:

1.可以在任何函数中读取全局变量的值

2.如何在函数中存在全局变量名字相同的局部变量,在函数中使用的局部变量的值

3.在函数内部想要修改全局变量的引用,需要添加global关键字 ,对变量进行声明为全局变量

4.声明周期

代码执行的时候被创建,代码执行结束, 被销毁

返回值-函数返回多个数据值               

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

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

函数参数

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

关键字传参

在函数调用的时候,指定数据值给到那个形参

混合使用

1.关键字传参必须写在位置传参的后面

2.不要给个一个形参传递多个数据值

缺省参数

缺省参数,默认参数

列表.pop()# 不写参数,删除最后一个

列表.sort(reverse)

1.定义方式

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

2.好处

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

如果传参  ,使用的就是传递的实参值,如果不传参,使用的就是默认值

def inforp(name,sex='man'):
    print(name,sex)


 
inforp('李明')           #李明 man
inforp('小明','女')       #小明 女

多址参数[可变参数/不定长参数]

print(1)

print(1,2)

print(1,2,3)

print(1,2,3,4)

当我们书写函数的时候,不确定参数的具体个数,可以使用不定长参数

-不定位置参数(不定长元组参数)

1.书写,在普通参数的前边,加上一个*,这个参数就变为不定长位置参数

2.特点,这个形参有接受任意多个位置传参的数据

3.数据类型,形参的类型是元组

4.注意,不定长位置参数 要写在普通参数的后面

5.一般写法,不定长参数的名字为args,即(*args)

-不定长关键字参数(不定长字典参数)

1.书写,在普通参数的前片,加上两个*,这个参数就变为不定长关键字参数

2.特点,这个参数可以接收任意多个关键字传参的数据

3.数据类型,形参的类型是字典

4.注意,不定长关键字参数,要写在所有参数的最后面 

5.一般写法,不定长关键字的名字 为kwargs,即(**kwargs)

完整顺序

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

        pass

def num_3(*args, **kwargs):
    num = 0
    for i in args:
        num += i
    for j in kwargs.values():
        num += j
    print(num)


num_3(1, 6, a=10)

list9=[1,6,3,6,4]
dict_7={'a':1,'b':6,'c':3,'d':6,'e':4}
num_3(*list9)  #20
num_3(**dict_7) #20

当形参需要放入列表或者元组或字典时,需要拆包,*列表/元组,**字典

-函数部分

--不定长参数的补充扩展

--匿名函数 lambda

-面向对象

匿名函数:就是用lambda关键字定义的函数

一般称为使用def 关键字定义的函数为   ,标准函数

匿名函数只能书写一行代码

匿名函数的返回值不需要returen,一行代码的结果就是返回值

语法:
lambda 参数:一行代码

#匿名函数一般不需要我们主动的调用,一般作为函数的参数使用

#我们在学习阶段为了查看匿名函数定义的是否正确,可以调用

func8 = lambda a,b:a*b

print(func8(1,6))  

使用场景:作为函数的参数

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

列表排序

列表.sort()升序

列表.sort(reverse=Ture)降序

#列表的排序,默认是对列表中的数据进行比大小,可以对数字类型和字符串进行比大小

#但是对于字典来说,就不知道该怎样比大小,此时,我们需要使用sort函数中的key这个参数,来指定字典比大小的方法

列表.sort(kye=lambda x:x[‘键’])

说明:匿名函数中的参数是列表中的数据,在sort 函数内部,会调用key这个函数(将列表中每个数据作为实参传递给形参)

从列表中的函数的返回值,对返回值进行比大小的操作<>

 字符串比大小

字符比大小,是比较字符对应的asscii码       

ord(字符)获取字符对应的asscii码

chr(asscii码)获取对应asscii码

面向对象

基本介绍

面向对象是一个编程思想(代码套路)

编程思想:

1.面向过程:

关注的是具体步骤的实现,所有的功能都自己书写

亲力亲为

定义一个个函数,最终按照顺序调用函数

2.面向对象

以上两种都属于写代码的套路(方法)最终目的都是为了将代码写出来,只不过  过程和思考方法不太一样

关注的是结果,谁能帮我做这件事

偷懒

找一个对象(),让对象去做

类的组成

1.组成(给多个事物起一个名字,代码中,满足大驼峰命名法(每个单词的首字母大写))

2.属性(事物的特征,即有什么,一般文字中的名词)

3.方法(事物的行为,即做什么,一般是动词)

类的抽象(类的设计)

类的抽象,其实就是找到类的类名,属性和方法

面向对象基本代码的书写      

1.定义类

先定义简单的类,不包含属性,在python中定义类需要使用关键字class

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

class 类名:

        #在缩进中书写的内容,都是类中的代码

        def 方法名(self):

                pass

2.创建对象

创建对象是使用  类名()进行创建,即

类名() 创建一个对象,这个对象在后续不能使用

变量=类名()#这个变量中保存的是对象的地址,一般可以称为这个变量为对象

3.调用方法

对象.方法名()

列表.sort()

列表.append() 

实例

class Cat:
    def eat(self):
        print('小猫还吃鱼')
    def drink(self):
        print('小猫爱喝水')




blue_cat=Cat()
blue_cat.eat()    #小猫还吃鱼
blue_cat.drink()  #小猫爱喝水

  self 的说明

从函数的语法上讲,self是形参,就可以是任意的变量名,只不过我们习惯性的将这个形参写作self,

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

对象的属性操作

添加属性

对象.属性名=属性值

--类内部添加

在内部方法中,self是对象

self.属性名=属性值

#在类中添加属性一般写作__init__方法中

-类外部添加

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

魔法方法

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

__init__方法

1.什么情况下会自动调用

    》创建对象之后会自动调用

2.有什么用,用在哪

      》1.给对象添加属性的,(初始化方法,构造方法)2.某些代码,在每次创建对象之后,都要执行,可以将这行代码写在__init__  方法

3.书写注意

》1.不要写错2.如果有除了self以外的参数,还要穿对应的实参

class Cat:
    def __init__(self,name,age):
        self.name =name
        self.age = age

    def show_S(self):
        print(f'小猫的名字是:{self.name},年龄:{self.age}')


blue_cat = Cat('黑猫',12)
blue_cat.show_S()  #小猫的名字是:黑猫,年龄:12

__str__方法

class Cat:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        # 方法必须返回一个字符串,只要是字符串就行
        return f'小猫的名字是:{self.name},年龄:{self.age}'


blue_cat = Cat('黑猫', 12)
print(blue_cat)  #小猫的名字是:黑猫,年龄:12

__ del__

__init__方法,创建对象后,自动调用

__del__方法,对象被销毁后,自动调用(遗言,自动处理)

家居案例

class Houseltem():
    def __init__(self, name, area):
        self.name = name
        self.area = area

    def __str__(self):
        return f'家具的名字为{self.name},占地面积{self.area}平米'


class House():
    def __init__(self, name, total_area):
        self.name = name
        self.total_area = total_area
        self.free_area = total_area
        self.item_list = []

    def __str__(self):
        return f'房子的户型是{self.name},总面积{self.total_area}m²,剩余面积{self.free_area}m²,家具名称为{self.item_list}'

    def add_item(self, item):
        if self.free_area > item.area:
            self.free_area -= item.area
            self.item_list.append(item.name)
            print(f'{item.name}添加成功')
        else:
            print(f'{item.name}添加失败')


chest = Houseltem('衣柜', 2)
bed = Houseltem('席梦思', 4)
table = Houseltem('餐桌', 1.5)
print(bed)
print(chest)
print(table)

结果   家具的名字为席梦思,占地面积4平米
家具的名字为衣柜,占地面积2平米
家具的名字为餐桌,占地面积1.5平米
房子的户型是三室一厅,总面积150m²,剩余面积150m²,家具名称为[]
席梦思添加成功
房子的户型是三室一厅,总面积150m²,剩余面积146m²,家具名称为['席梦思']

私有和公有

1.在python中定义的方法和属性,可以添加访问控制权限(即在什么地方可以使用这个属性个方法)

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

3.公有权限

             》直接书写的方法的属性,都是公有的

              》公有方法和属性,可以在任意地方访问和使用

4.私有权限

        》在类内部,属性名或者方法名 在前面加上两个 下划线,这个属性或这方法就变为私有的

        》私有方法和属性,只能在类的内部使用

5.什么时候定义私有

        1.某个属性或者方法,不想在类外部访问和使用,就定义为私有

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

        3.开发中,会有需求文档,确定什么私有

继承

1.继承描述的类与类之间的关系

2.继承的好处:减少代码的冗余(相同的代码不需要多次重复书写),可以直接使用

语法

class A:                #没有写父类,也有父类,object,object类是python中最顶级的类
        pass

class B(A):
        pass

1.A类,称为是父类(基类)

2.B类,称为是子类(派生类)

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

class Animal():
    def eat(self):
        print('吃东西')
class sleep(Animal):
    def sleep(self):
        print("睡觉")
class xtq(sleep):
    pass
a = xtq()
a.eat()    #吃东西
a.sleep()   #睡觉

结论

python中 对象.方法()调用方法

1.现在自己的类中去找有没有这个方法,如果有,直接调用

2.如果没有去父类中 查找,如果有,直接调用

3.如果没有,去父类的父类去查找,如果有,直接调用

4..

5.如果object 类中有,直接调用,如果没有,直接报错

覆盖

1.直接在子类中定义和父类相同的方法

.2.直接在方法中重新书写

扩展

1.直接在子类中定义和父类相同的方法

2.在合适的地方调用父类中方法  super().方法()

3.书写添加的新功能

多态

1.是一种写代码,调用的技巧

2.同一个方法,传入不同的对象,执行得到不同的结果,这种现象称为多态

属性和方法

python中一切皆对象

即 使用class定义的类        

方法的划分

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

实例方法

-定义

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

class Demo:

        def func(self):#参数一般写作self,表示 实例对象
                pass

定义时机(什么时候用)

类方法(会用)

-定义

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

class Demo:

        @classmethod

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

                pass.

定义时机(什么时候用)

1.前提,方法中不需要使用 实例属性(即self)

2.用到了类属性,k可以将这个方法定义为类方法,(也可以定义为实例方法)

调用

#1.通过类对象调用

类名.方法名()#不需要给cls传参,python解释器自动传递

#2.通过实例对象调用

实例.方法名()#不许要给cls传参,python解释其回自动传递

import random


class Game():
    top_score = 0

    @staticmethod
    def show_help():
        print('这是游戏的帮助信息')

    @staticmethod
    def show_top_score():
        print(f'游戏最高分{Game.top_score}')

    @classmethod
    def start_game(cls):
        score = random.randint(10, 100)
        print(f'本次游戏得分为:', score)
        if score > cls.top_score:
            cls.top_score = score
        else:
            pass
xm = Game()
xm.start_game()
xm.show_top_score()
xm.start_game()
xm.show_top_score()

补充

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

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

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

面试题可能回问:is  和 ==是否相同

==只判断是否相同  而is判断引用是否相同

文件

计算机的文件 就是存贮在某种长期存储设备上的一段数据

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

-文本文件

--能够使用记事本软件打开(能够使用记事本转换为文字)

txt   ,md ,py,html,css,js,json

文件操作

1.打开文件

def open(file, mode='r', buffering=None, encoding=None): # known special case of open

参数file:是要打开的文件,类型是字符串,文件的路径可以是相对路径,也可以是绝对路径,建议写相对路径

》参数mode:默认参数(缺省参数),表示的是打开文件的方式

                     》r:read 只读打开

                      》w :write 只写打开

                        》a:append 追加打开,在文件的末尾写入内容

》参数 encoding:编码方式,(文字和二进制如何进行转换的)

        》gbk:将一个汉字转换为2个字节二进制

        》utf-8:常用将一个汉字转换为3个字节的二进制

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

2.读或者写文件

向文件中写入指定的内容

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

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

读文件

将文件中的内容读取出来

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

文件对象.read(n)

#参数n表示读取多少个字符,一般不写,表示读取全部内容

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

3.关闭文件

文件对象.close()

使用with open 打开文件

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

with open(file,mode,‘encoding=‘utf-8’’)as 变量:
 

按行读取文件

按行读取文件:一次读取一行内容

文件对象.readline()

json文件的处理

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

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

json文件的语法

1.json文件的后缀是.json

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

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

4.json中的对象是由键值对组成的,每个数据之间使用逗号隔开,但最后一个数据后面不要写逗号

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

6.json中的数据类型

数字类型---》int  float

string字符串--》str

布尔类型 true,false----》 Ture ,False

null---》None

json的写入

步骤

1.导包 import  josn

2.写(w)方式打开文件

3.写入

json.dump(Python 中的数据类型,文件对象

读取

json.load()

异常

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

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

捕获异常     

基本语法

try:

        书写可能发生异常的代码

except:#任何类型的异常都能捕获

        发生了异常执行的代码

try:

        书写可能发生异常的代码

except 异常类型:#只能捕获指定类型的异常,如果不是这个异常,还是会报错 

        发生了异常执行的代码

捕获多个指定类型异常

try:

        书写可能发生异常的代码

except 异常类型1:

        发生了异常1执行的代码

except 异常类型2:

        发生了异常2执行的代码

except......:

try:
    num = input('请输入数字:')
    num = int(num)
    print(num)
    a = 10 / num
    print(f'{a}')

except ValueError:
     print('类型错误,请输入正确的数字')
except ZeroDivisionError:
      print('除数不能为0')
#请输入数字:aaa
#,请输入正确的数字

完整异常捕获

try:

        书写可能发生异常的代码

except 异常类型1:

        发生了异常1执行的代码

except Exception as 变量:

#Exception 是常见异常的父类,这里书写Exception,可以捕获常见的  所有异常,as  变量,这个变量是个异常类的对象,print(变量)可以打印异常信息

        发生其他类型的异常,执行代码

else:

        没有发生异常执行的代码

finally:

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

异常传递

模块和包

1.python源代码文件就是一个模块

2.模块中定义的变量 函数 类,都可以让别人使用,可以使用别人定义的

3.想要使用别人模块中的内容工具(变量,类,函数),必须先导入模块才能使用

4.我们自己写的代码,想要作为模块使用,代码的名字需要满足标识符的规则(由数字字母下换线开头,不能用数字开头)

导入模块的语法

方式一

import 模块名

#使用模块中的内容

模块名.工具名

方式二

from 模块名 import 工具名

工具名  #如果是函数和类需要加括号

举例

form random import randint

randint(a,b)

方式三(基本不用)

form 模块名 import *  #将模块中所有的内容都导入

对于导入的模块和工具可以使用as 关键字给其起别名

注意:如果起别名,原来的名字就不能用了,只能使用别名

模块的查找顺序

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

没有找到,报错

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

__name__的作用        

1.每个代码文件都是一个模块

2.在导入模块的时候,会执行模块中的内容

3.__name__变量

1).__name__变量是python解释器自动维护的变量

2)__name__变量,如果代码直接运行,值是‘’__main__‘’

3)如果__name__变量,如果代码是被导入执行,值是模块名(即代码文件名)

在被导入时,不想被执行的代码可以写在  if __name__=="__main__":代码缩进中

:包(pacakage)

在python中,包是一个目录,只不过在这个目录,只不过在这个目录存在一个文件__init__.py(可以是空)

功能相近或者相似的代码放在一起

在python中使用的时候,不需要区别包和模块,使用方式都是一样的

random 模块

json  包(目录)

1.import 包名

2.alt  回车  快捷导入

UnitTest框架

unittest核心要素(的组成)

1.TestCase(最核心的模块)

TestCase(测试用例),注意这个测试用例是unittest框架的组成部分,不是手工和自动化中我们所说的用例

主要作用:每个TestCase(测试用例)都是一个代码文件,在这个代码文件中来书写真正的用例代码

2.TestSuit

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

3.TestRunner

TestRunner(测试执行,测试运行),用来执行TestSuit(测试套件)的

4.TestLoader

TestLoader(测试加载),功能是对TestSuit(测试套件)功能的补充,用来管理 组装(打包)多个TestCase(测试用例)的

5.Fixture

测试夹具,作用:书写在TestCase(测试用例)代码中的,是一种代码结构,在每个方法执行前后都会执行的内容

TestCase

步骤:1.导包(Unittest)2.自定义测试类 3.在测试中书写测试方法  4.执行用例

import unittest


class TestDemo(unittest.TestCase):
    def test_method1(self):
        print('测试方法1')

    def test_method2(self):
        print('测试方法2')
#将光标放在类名后面就会执行后面的所有方法
#将光标放在方法后只执行这个方法

常见问题

1.文件名必须是字母数字下划线,不能以数字开头

2.文件是python进行运行的,必须修改环境变量python unittest

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

TestSuite&TestRunner

TestSuite(测试套件):管理  打包  组装  TestCase(测试用例)文件的

TestRuner:执行TestSuite(套件)

步骤

1.导包(unittest)

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

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

4.实例化运行对象

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

代码

TestSuit(测试套件):用来管理多个TestSuit(测试用例)的

#导包
import unittest

from news import testDemo1
#实例化(创建对象)套件对象
suite = unittest.TestSuite()
#使用套件对象添加  套件对象.addTest(类名(方法)
suite.addTest(testDemo1('test_method1'))
suite.addTest(testDemo1('test_method2'))
#实例化运行对象
runner = unittest.TextTestRunner()
#使用运行对象去执行套件对象
#运行对象.run(套件对象)
runner.run(suite)

#导包
import unittest

from news import testDemo1
#实例化(创建对象)套件对象
suite = unittest.TestSuite()
#使用套件对象添加  第二种方法套件对象.addTest(unittest.makeSuite(类名))
suite.addTest(unittest.makeSuite(testDemo1))

#实例化运行对象
runner = unittest.TextTestRunner()
#使用运行对象去执行套件对象
#运行对象.run(套件对象)
runner.run(suite)

TestLoader(测试加载)

TestLoader(测试加载),作用和Testsuite的作用是一样的,对TestSuite功能的补充,用来组装测试用例的

比如:如果TestCase的代码文件有很多,(10,20,30)

使用步骤

1.导包

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

3.实例化运行对象

4.运行对象执行套件

#TestLoader的使用

import  unittest

unittest.TestLoader().discover(‘用例所在的路径(相对)’,‘用例代码文件名’)

suite=unittest.TestLoader().discover(‘./case’,‘hm*.py’)

suite=unittest.TestLoader().discover(‘./case’,*test*.py’)

#实例化运行对象并且执行

unittest.TextTestRunner().run(suite)

Fixture(测试夹具)

在某些特定的情况下回自动执行

方法级别(掌握)

#方法执行之前

def setup(self):

        每个方法执行之前都会执行

#方法执行之后

def  teardown(self):
        每个方法执行后都会执行

        pass

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

#类中所有方法之前

@classmethod

def setupClass(cls):

        pass

#勒种所有方法之后

@classmethod

def teardwon(cls):

        pass

模块级别(了解)

#模块级别的需要写在类的外边直接定义函数即可

#代码文件之前

def setupModule():
        pass

#代码文件之后

def teardownModule():

        pass

方法级别和类级别的 前后的方法,不需要同时出现,根据用例代码的需要自行选择使用

断言

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

断言的结果有两种:
》True,用例通过

》Flase,代码抛出异常,用例不通过

asserEqual

asserEqual(预期结果,实际结果)#判断预期结果和实际结果是否相等

1.如果相等,用例通过

2.如果不相等,用例不通过,抛出异常

assertln

assertlin(预期结果,实际结果) #预期结果是否包含在实际结果中

1.包含,用例通过

2.不包含,用例不通过,抛出异常

 参数化

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

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

工作场景:

1.测试数据一般存放在json文件中

2.使用代码读取json文件,提取我们想要的数据  --》[(),()]  or  [[],[]]

安装插件

-联网安装(在cmd窗口)

pip install parameterized

可以在pycha终端中下载

参数化代码

1.导包

2.定义测试类

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

4.组织测试数据并传参

跳过

#直接将测试函数标记跳过

@unittest.skip(‘跳过原因’)

@unittest.skipIf(跳过条件,‘跳过’)

import unittest
version=29


class TestDemo(unittest.TestCase):
    @unittest.skip('没原因就跳过')
    def test_1(self):
        print('测试方法一')
    @unittest.skipIf(version>=30,'版本大于等于30,不用测试')
    def test_2(self):
        print('测试方法二')

    def test_3(self):
        print('测试方法三')

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值