Python介绍
python常用于回归测试。
python+selenium web自动化(功能测试转换为代码)
python+appium 移动端(手机端app)自动化
python+ requests 接口
Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。python是轻量级语言。
Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构。
Python 是一种解释型语言: 这意味着开发过程中没有编译 这个环节。类似于PHP和Perl语言。
Python 是交互式语言: 这意味着,您可以在一个 Python 提示符 >>> 后直接执行代码。
Python 是面向对象语言: 这意味着Python支持面向对象的风格或代码封装在对象的编程技术。
Python 是初学者的语言: Python 对初级程序员而言,是一种伟大的语言,它支持广泛的应用程序开发,从简单的文字处理到 WWW 浏览器再到游戏。
Python基础代码 标识符
第一个字符必须是字母表中字母或下划线**_** ,不能以数字开头。
驼峰命名法:
大驼峰(又称帕斯卡命名法Pascal Case):通常用于标识符(如变量名、函数名、类名等)的命名。在帕斯卡命名法中,每个单词的首字母都大写,单词之间没有下划线或其他分隔符。:MyName
小驼峰(Camel Case):通常用于命名变量、函数、方法等标识符。在小驼峰命名法中,除了第一个单词的首字母小写外,后续单词的首字母都大写,单词之间没有下划线或其他分隔符。,其他大写:myName
下划线连接法(Snake Case):每个单词之间用下划线连接my_name
变量一般使用下划线法
标识符的其他的部分由字母、数字和下划线组成。
标识符对大小写敏感。
在 Python 3 中,可以用中文作为变量名,非 ASCII 标识符也是允许的了。
python保留字
PYTHON
1 2 3 4 >['False' , 'None' , 'True' , 'and' , 'as' , 'assert' , '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' ]
多行语句 Python 通常是一行写完一条语句,但如果语句很长,我们可以使用反斜杠 ** 来实现多行语句,例如:
PYTHON
1 2 3 total = item_one + \ item_two + \ item_three
在 [], {}, 或 () 中的多行语句,不需要使用反斜杠 ****,例如:
PYTHON
1 2 total = ['item_one' , 'item_two' , 'item_three' , 'item_four' , 'item_five' ]
数字类型
int (整数), 如 1, 只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。
bool (布尔), 如 True。
float (浮点数), 如 1.23、3E-2
complex (复数), 如 1 + 2j、 1.1 + 2.2j
输出print()
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 x = "a" y = "b" print (x)print (y)print ('---------' )print (x, end=" " )print (y, end=" " )print ()
格式化输出
PYTHON
1 2 3 4 5 6 print ("%s" ,%str ) print ("%d" ,%a) print ("%06d" ,%b) print ("%f" ,%c) print (".2f" ,%d) print ("%%" )
PYTHON
1 2 3 4 name = 'ana' age = 18 height = 1.752 print ("her name is %s,her age is %d,her height is %.2fm" % (name, age, height))
PYTHON
1 2 num = 90 print ('percentage %d%%' % num)
F-string(f字符串的格式化方法)
1 2 3 1. 需要在字符串前面加上f""或者F"" 2. 占位符号统一变为{variable name} 3. 需要填充的变量写在{}
PYTHON
1 2 3 4 5 6 7 8 stu_num = 1 num = 90 name = 'ana' age = 19 height = 1.821 print (f'her name is {name} ,age is {age} ,height is {height:.2 f} m,student number is {stu_num:06d} ,percentage is {num} %' )
PYTHON
1 2 3 a = input ('输入你心中想的内容:' ) print ("你输入的是" + a)print (type (a))
输入的内容类型是字符串类型
类型转换
PYTHON
1 2 3 4 5 6 7 a = input ('输入你的年龄:' ) b = int (a) print ("你的年龄是" , b)print ("一年后你的年龄是" , int (a) + 1 )print (type (a))print (type (b))
int()
可以将其他类型转换成int类型
可以将float类型转换成整型
可以将整数类型字符串转换为整型
float()
可以将其他类型转换成float类型
可以将int类型转换成浮点型
可以将数字类型字符串(整数、小数)转换为浮点型
str()
可以将其他类型转换成字符串类型
任何类型都可以使用str()将其转换成字符串,一般都是直接加引号
import与from…import 在 python 用 import
或者 from...import
来导入相应的模块。
将整个模块(somemodule)导入,格式为:import somemodule
从某个模块中导入某个函数,格式为: from somemodule import somefunction
从某个模块中导入多个函数,格式为: from somemodule import firstfunc, secondfunc, thirdfunc
将某个模块中的全部函数导入,格式为: from somemodule import *
import somemodule as alias
导入模块指定别名alias
python中的三种波浪线和pep
Python基本数据类型 Python 中的变量不需要声明。每个变量在使用前都必须赋值,如果事先不知道赋什么数值,可以先赋值None,variable = None
进行初始化。变量赋值以后该变量才会被创建。
在 Python 中,变量就是变量,它没有类型,我们所说的”类型”是变量所指的内存中对象的类型。变量名在赋值时,实际上是将对象的引用(即内存地址)赋值给变量名。因此,变量名实际上是对象的引用,而不是直接对内存地址的引用。
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 import ctypesa = 12 b = a print ('12的内存地址:' , id (a))print ('通过内存地址140714148648072访问值:' , ctypes.cast(140714148648072 , ctypes.py_object).value) print ('12的内存地址:' , id (b))a = 30 print ('a现在指向30的内存空间,通过a访问' , a)print ('30的内存地址:' , id (a))print ('b仍然指向之前的引用' , b) print ('b指向的内存地址' , id (b))
Python允许你同时为多个变量赋值,连续赋值从右往左,分别赋值按位置进行赋值。例如:
PYTHON
1 2 3 4 5 6 7 8 9 10 11 a = b = c =1 c = 1 b = c a = b a,b,c=1 ,2 ,'hello' a = 1 b = 2 c = 'hello'
标准数据类型 Python3 中常见的数据类型有:
Number(数字)
整数(int): 表示整数值,例如 42
或 -10
。
浮点数(float): 表示带有小数点的数值,例如 3.14
或 -0.001
。
String(字符串):表示文本数据,用单引号 ' '
或双引号 " "
括起来,例如 'hello'
或 "world"
。
bool(布尔类型):表示逻辑值,只有两个值:True
和 False
。
List(列表):表示有序的可变集合,可以包含任意类型的元素,例如 [1, 2, 'hello']
。
Tuple(元组): 表示有序的不可变集合,可以包含任意类型的元素,例如 (1, 2, 'hello')
。
Set(集合):表示无序的不重复元素的集合,例如 {1, 2, 3}
。
Dictionary(字典):表示键值对的集合,其中每个键都对应一个值,例如 {'name': 'Alice', 'age': 30}
。
NoneType(空值): 表示空值或者缺失值,用 None
表示。
bytes(字节串): 表示二进制数据,例如 b'hello'
。
-
import sys
s = "hello"
b = b'hello'
print(sys.getsizeof(s)) # 获取字符串对象 s 占用的内存空间大小
print(sys.getsizeof(b)) # 获取字符串对象 b 占用的内存空间大小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32  Python3 的六个标准数据类型中: - **不可变类型(3 个):**可变类型在创建后其内容无法被修改,每次对不可变类型进行操作时,都会创建一个新的对象 Number(数字)、String(字符串)、Tuple(元组); - **可变类型(3 个):**在 Python 中,可变类型是指可以在创建后修改其内容的数据类型。可变类型的数据结构在内存中的内容可以改变,而不会改变其在内存中的地址。这意味着,对可变类型对象进行操作时,不会创建新的对象,而是直接修改原始对象。 List(列表)、Dictionary(字典)、Set(集合)。 - - ```python list1 = [1, 2, 3] print('list1的内存地址:', id(list1)) print('list1[0]:1的内存地址:', id(list1[0])) print('list1[1]:2的内存地址:', id(list1[1])) print('list1[2]:3的内存地址:', id(list1[2])) list1.append(5) print('list1的内存地址:', id(list1)) list1 = [1, 3, 4] # 指向了一个新的列表对象,原来的列表对象因为没有变量指向它,会被回收 print('list1的内存地址:', id(list1)) print('list1[0]:1的内存地址:', id(list1[0])) print('list1[1]:3的内存地址:', id(list1[1])) print('list1[2]:4的内存地址:', id(list1[2])) x = 42 print('x的内存地址', id(x)) print('x+1的内存地址', id(x + 1))
number数字 Python3 支持 int、float、bool、complex(复数) 。
注意:
数值的除法包含两个运算符:**/** 返回一个浮点数,**//** 返回一个整数。
在混合计算时,Python会把整型转换成为浮点数。
查看类型 type()
type(obj)
函数返回对象 obj
的类型对象。
例如,type(5)
返回 <class 'int'>
,表示整数对象的类型是 int
类型。
PYTHON
1 2 a,b,c,d=2 ,3.14 ,True ,3 +4j print (type (a),type (b),type (c),type (d))
isinstance()
isinstance(obj, classinfo)
函数用于检查对象 obj
是否是指定类型 classinfo
的实例,或者是其子类的实例。
classinfo
参数可以是类型对象、类型元组或类型列表。如果 obj
是 classinfo
类型的实例或其子类的实例,则返回 True
;否则返回 False
。
例如,isinstance(5, int)
返回 True
,表示整数对象 5
是 int
类型的实例。
PYTHON
1 print (isinstance (a,int ))
一定要注意二者的区别和使用方法
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class A (): pass class B (A ): pass a = A() b = B() print (type (a))print (type (b))print (isinstance (b, A))print (isinstance (b, B))
String字符串
字符串的截取 字符串的截取的语法格式如下:
变量[头下标:尾下标]
索引值以 0 为开始值,-1 为从末尾的开始位置。
尾下标对应的字符不包含
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 str = 'abcdefghijk' print (str )print ("输出字符串第一个字符:" + str [0 ])print ("输出字符串最后一个字符:" + str [-1 ])print ("输出字符串第一个到第3个字符:" + str [0 :3 ])print ("输出字符串第一个到倒数第二个个字符:" + str [0 :-1 ])print ("输出字符串第一个到第3个字符:" + str [:3 ])print ("从字符串倒数第三个字符开始输出:" + str [-3 :])print ("字符串的每个字符间隔1个输出(步长为2):" + str [::2 ])print ("字符串输出2次:" + str * 2 )print ("字符串拼接输出:" + '你好' + str )print ("反转字符串:" + str [::-1 ])print ('hello\npython' )print (r'hello\npython' )
相关函数 len() len()可以用来获取字符串长度
查找方法find()
PYTHON
1 2 3 4 5 6 7 8 字符串.find(sub_str,start,end) 返回结果: 1. 找到了,返回第一次出现的下标(sub_str第一个字符在字符串中的下标)2. 没有找到,返回-1
PYTHON
1 2 3 str = 'abcdefghijk' print (str .find('abc' ))
PY
1 2 3 4 str = 'ana and luke and lei' num = str .find('and' ) print (str .find('and' , num + 1 ))
PYTHON
1 2 3 4 5 6 7 for i in range (1 , 100 ): if i % 7 == 0 or str (i).find('7' ) != -1 : print ("过" ) else : print (i)
字符串替换replace()
PYTHON
1 2 3 4 字符串.replace(old_str,new_str,count)
PYTHON
1 2 3 4 5 6 str1 = 'good good study' str2 = str1.replace('g' , 'G' ) print ("str1=" , str1)print ("str2=" , str2)
PYTHON
1 2 3 4 5 6 str1 = 'good good study' str2 = str1.replace('good' , 'GOOD' ,1 ) print ("str1=" , str1)print ("str2=" , str2)
PY
1 2 3 4 5 6 7 str1 = 'good good study' str2 = str1.replace('good' , 'GOOD' , ) str3 = str2.replace('GOOD' , 'good' , 1 ) print ("str2=" , str2)print ("str3=" , str3)
字符串的拆分spilt()
PYTHON
1 2 3 4 5 字符串.split.(sep,maxsplit)
PYTHON
1 2 3 4 5 str = "Hello,my name is Elora" list1 = str .split() print (list1)print (str .split(maxsplit=1 ))
字符串的连接join()
PYTHON
1 2 3 4 5 6 list1 = ['hello' , 'world' , 'you' ] str1 = ' ' .join(list1) print (str1)str2 = ' and ' .join(list1) print (str2)
字符串格式化
1 2 3 字符串.format() 1. 在需要使用变量的地方使用{}占位 2. '{},{}...'.format(变量,变量)...
PYTHON
1 2 3 4 5 6 7 stu_num = 1 num = 90 name = 'ana' age = 19 height = 1.821 print ('her name is {},age is {},height is {:.2f}m,student number is {:06d},percentage is {}%' .format (name, age, height, stu_num, num))
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 name = 'Alice' age = 30 message = 'My name is {0} and I am {1} years old.' .format (name, age) print (message)message = 'My name is {name} and I am {age} years old.' .format (name='Alice' , age=30 ) print (message)pi = 3.14159 formatted_pi = 'The value of pi is {:.2f}' .format (pi) print (formatted_pi) message = 'My name is {0} and I am {age} years old.' .format (name, age=30 ) print (message)
bool布尔类型 在 Python 中,True 和 False 都是关键字,表示布尔值。
布尔类型特点:
布尔类型只有两个值:True 和 False。
布尔类型可以和其他数据类型进行比较,比如数字、字符串等。在比较时,Python 会将 True 视为 1,False 视为 0。
布尔类型可以和逻辑运算符一起使用,包括 and、or 和 not。这些运算符可以用来组合多个布尔表达式,生成一个新的布尔值。
布尔类型也可以被转换成其他数据类型,比如整数、浮点数和字符串。在转换时,True 会被转换成 1,False 会被转换成 0。
注意: 在 Python 中,所有非零的数字和非空的字符串、列表、元组等数据类型都被视为 True ,只有 0、空字符串、空列表、空元组 等被视为 False。因此,在进行布尔类型转换时,需要注意数据类型的真假性。
list列表
列表可以完成大多数集合类的数据结构实现。列表中元素的类型可以不相同 ,它支持数字,字符串甚至可以包含列表(嵌套)。
列表是写在方括号 [] 之间、用逗号分隔开的元素列表。
和字符串一样,列表同样可以被索引和截取,列表被截取后返回一个包含所需元素的新列表。截取的语法格式:变量[头下标:尾下标]
索引值以 0 为开始值,**-1** 为从末尾的开始位置。
PYTHON
1 2 3 list1 = list () print (list ('hello' ))
PYTHON
1 2 3 list1 = list () print (list (' h ello' ))
列表的切片
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 list1 = ['abcd' , 78910 , 2.233333 , 'hello' , 351 ] tinylist1 = [123 , 'abcdefg' ] print (list1)print (tinylist1)print ("打印整个列表:" , end=' ' )print (list1)print ("打印列表的第一个元素:" , end=' ' )print (list1[0 ])print ("打印列表第二到第三个元素(包含第三个元素):" , end=' ' )print (list1[1 :3 ])print ("打印列表第二到第三个元素(不包含第三个元素):" , end=' ' )print (list1[1 :2 ])print ("打印列表第二个元素:" , end=' ' )print (list1[1 ])print ("打印列表第三个元素到末尾:" , end=' ' )print (list1[2 :])print ("打印tiny列表两次" , end=' ' )print (tinylist1 * 2 )print ("打印两个列表" , end=' ' )print (tinylist1 + list1)print ("打印两个列表合并后第二个到第五个元素" , end=' ' )print ((tinylist1 + list1)[1 :6 ])print ("逆转list" , end=' ' )print (list1[::-1 ])
列表查询相关操作 数据下标index()
PYTHON
1 2 3 列表.index(el,start,end)
PYTHON
1 2 3 4 mylist = [1 , 3 , 5 , 7 , 2 , 3 ] num = mylist.index(3 ) print ("出现3的下标是:" , num)print ("出现4的下标是:" , mylist.index(4 ))
判断是否存在in()
统计出现次数count()
列表修改数据
PYTHON
1 2 3 4 5 6 list1 = ['abcd' , 78910 , 2.233333 , 'hello' , 351 ] list1 = [12321 ] list1[1 :3 ] = ['a' , 'b' ] list1[3 :4 ] = [444 ] print (list1)
PYTHON
1 2 3 4 5 6 list1 = ['abcd' , 78910 , 2.233333 , 'hello' , 351 ] list1[0 ] = 12321 list1[1 :3 ] = ['a' , 'b' ] list1[3 :4 ] = [444 ] print (list1)
列表添加数据 尾部添加(最常用)
指定下标位置添加
PYTHON
1 2 3 4 5 6 7 8 9 mylist = ['hello' , 'world' , 'and' ] mylist.append('you' ) print (mylist)mylist.insert(1 , 'Lily' ) print (mylist)mylist.append(['him' , 'and' ]) print (mylist)mylist.insert(1 , ['Manny' , 'Sue' ]) print (mylist)
列表合并extend()
PYTHON
1 2 3 4 5 6 7 8 9 mylist = ['我' , '爱' ] list2 = list ('螺蛳粉' ) mylist.extend(list2) print (mylist)mylist.append(list2) print (mylist)
列表删除 在列表中删除中间的数据,后面的数据会向前移动
根据下标删除
PYTHON
1 2 3 4 5 列表.pop(下标) del .列表[下标]
根据数据值删除
PYTHON
1 2 3 4 list1=['h' ,'h' ,'h' ,'h' ,'h' ,'h' ,'h' ,'h' ,'h' ,'h' ,'o' ,'l' ] while 'h' in list1: list1.remove('h' ) print (list1)
清空数据(一般不用)
列表的反转和逆置
PYTHON
1 2 1. 列表[::-1 ] 2. 列表.reverse()
PYTHON
1 2 3 4 5 list1=list ('hello' ) print (id (list1))list1.reverse() print (list1)print (id (list1))
列表的复制
PYTHON
1 2 3 4 5 6 1. 使用切片变量 = 列表[:] 2. 使用copy方法变量 = 列表.copy() 列表1 = 列表2
PYTHON
1 2 3 4 5 6 7 list1=['h' , 'e' , 'l' , 'l' , 'o' ] list2=['h' , 'e' , 'l' , 'l' , 'o' ] list3=list1.copy() print (id (list1))print (id (list2))print (list3)print (id (list3))
列表的排序 列表的排序一般是针对数字进行排序
PYTHON
1 2 列表.sort() 列表.sort(reverse=True )
列表去重 去除列表中重复的数据
错误示范
PYTHON
1 2 3 4 5 my_list = [1 , 23 , 33 , 11 , 2 , 23 , 3 , 2 , 1 , '3' , 3 ] for i in my_list: while (my_list.count(i) > 1 ): my_list.remove(i) print (my_list)
当检测到列表中该数据需要删除时,列表后方数据会向前移动,所以紧跟在被删除数据后方的元素会不参与遍历
正确示范 思想:放入新容器
PYTHON
1 2 3 4 5 6 7 8 my_list = [1 , 23 , 33 , 11 , 2 , 23 , 3 , 2 , 1 , '3' , 3 ] new_list=[] for i in my_list: if i not in new_list: new_list.append(i) else : continue print (new_list)
利用集合set特点
缺点:不能保证数据在原列表中的顺序(一般不考虑)
元组tuple
PYTHON
1 2 mytuple = tuple (list ) mytuple1 = tuple (str )
元组中只包含一个元素时,需要在元素后面添加逗号 , ,否则括号会被当作运算符使用:
PYTHON
1 2 3 4 5 tuple1 = (1 ) tuple2 = (1 ,) print (type (tuple1), tuple1)print (type (tuple2), tuple2)
元组的常用方法
没有修改方法
元组中可以使用下标和切片获取数据
元组中存在index方法
元组中存在count方法
可以使用in操作
字典
字典是另一种可变容器模型,且可存储任意类型对象。
字典的每个键值 key=>value 对用冒号 : 分割,每个对之间用逗号(, )分割,整个字典包括在花括号 {} 中 ,格式如下所示:
PYTHON
1 变量 = {key1 : value1, key2 : value2, key3 : value3 }
键必须是唯一 的,但值则不必。值可以取任何数据类型,但键必须是不可变类型,键一般是字符串,可以是数字,不能是列表 。
字典不能转化成列表、元组和字符串
PYTHON
1 2 3 4 5 6 7 8 9 10 dict1 = {} print (type (dict1), dict1)dict2 = dict () print (type (dict2), dict2)dict3 = {'name' : 'Marry' , 'age' : '32' , 'height' : '1.78' , 'is married' : True , 'hobbies' : ['painting' , 'music' ]} print (dict3)print (len (dict3))
字典的增加修改
PYTHON
1 2 3 字典[键]=数据值 1. 如果键已经存在,就是修改数据值2. 如果键不存在,就是添加数据(即添加键值对)
PYTHON
1 2 3 4 5 6 7 8 dict1 = {'name' : 'Marry' , 'age' : 32 , 'height' : '1.78' , 'is married' : True , 'hobbies' : ['painting' , 'music' ]} print (dict1)dict1['gender' ] = 'female' print (dict1)dict1['age' ] = 33 print (dict1)dict1['hobbies' ].append('studying' ) print (dict1)
PYTHON
1 2 3 4 5 6 7 list1 = [] for i in range (0 , 3 ): dict1 = {} dict1['name' ] = input ("请输入姓名" ) dict1['age' ] = input ("请输入年龄" ) list1.append(dict1) print (list1)
字典的删除
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 dict1 = {'name' : 'Marry' , 'age' : '32' , 'height' : '1.78' , 'is married' : True , 'hobbies' : ['painting' , 'music' ], 'gender' : 'female' } del dict1['gender' ]print (dict1)dict1.pop('age' ) print (dict1)dict1['hobbies' ].pop(0 ) print (dict1)dict1['hobbies' ].remove('music' ) print (dict1)dict1.clear() print (dict1)
字典的查询 字典中没有下标,要获取数据需要使用键来获取
PYTHON
1 2 3 4 5 6 7 8 dict1 = {'name' : 'Marry' , 'age' : '32' , 'height' : '1.78' , 'is married' : True , 'hobbies' : ['painting' , 'music' ]} print (dict1['name' ])print (dict1.get('name' ))print (dict1.get('gender' ))print (dict1.get('gender' , 'secret' ))print (dict1['hobbies' ][0 ])print (dict1.get('hobbies' )[0 ])print (dict1.get('address' ,'no info' ))
字典的遍历 对字典的键进行遍历
PYTHON
1 2 3 4 1. for key in 字典: print (key) 2. for key in 字典.keys(): print (key)
对值进行遍历
PYTHON
1 2 for value in 字典.values(): print (value)
对键值对进行遍历
PYTHON
1 2 for k, v in 字典.items(): print (k,v)
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 dict1 = {'name' : 'Marry' , 'age' : '32' , 'height' : '1.78' } for k in dict1: print (k) for k in dict1.keys(): print (k) print ('-' * 30 )for v in dict1.values(): print (v) print ('-' * 30 )for k, v in dict1.items(): print (k, v)
容器总结
字符串,列表,元组支持加法运算
字符串、列表、元组支持乘上一个整数
len()在容器中(str、list、dict、tuple)都可以使用
in 在容器中都可以使用,在字典中判断字典的key是否存在
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 my_list = [{'id' : 1 , 'money' : 10 }, {'id' : 2 , 'money' : 20 },{'id' : 3 , 'money' : 30 },{'id' : 4 , 'money' : 40 }] def func (): for element in my_list: if element['id' ] % 2 == 0 : element['money' ] += 10 else : element['money' ] += 20 func() print (my_list)
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 my_dict = {'登录' : [{'desc' : '正确的用户名密码' , 'username' : 'admin' , 'password' : '123456' , 'expect' : '登录成功' }, {'desc' : '错误的用户名' , 'username' : 'root' , 'password' : '123456' , 'expect' : '登录失败' }, {'desc' : '错误的密码' , 'username' : 'admin' , 'password' : '123123' , 'expect' : '登录失败' }, {'desc' : '错误的用户名和密码' , 'username' : 'aaa' , 'password' : '123123' , 'expect' : '登录失败' }], '注册' : [{'desc' : '注册1' , 'username' : 'abcd' , 'password' : '123456' }, {'desc' : '注册1' , 'username' : 'xyz' , 'password' : '123456' }]} opt = input ("请输入信息:登录/注册" ) info_list = [] if opt == '登录' : print ("获取登录数据" ) for i in my_dict.get('登录' ): my_tuple = (i.get('username' ), i.get('password' ), i.get('expect' )) info_list.append(my_tuple) print (info_list) elif opt == '注册' : print ("获取注册数据" ) for i in my_dict.get('注册' ): my_tuple = (i.get('username' ), i.get('password' )) info_list.append(my_tuple) print (info_list) else : print ("输入错误" )
Python运算符 算术运算符 以下假设变量 a=10,变量 b=21:
运算符
描述
实例
+
加 - 两个对象相加
a + b 输出结果 31
-
减 - 得到负数或是一个数减去另一个数
a - b 输出结果 -11
*
乘 - 两个数相乘或是返回一个被重复若干次的字符串
a * b 输出结果 210
/
除 - x 除以 y(返回浮点类型)
b / a 输出结果 2.1
%
取模 - 返回除法的余数
b % a 输出结果 1
**
幂 - 返回x的y次幂
a**b 为10的21次方
//
取整除 - 往小的方向取整数
>>> 9//2 4 >>> -9//2 -5
优先级:() > ** > * / // % > + -
比较运算符 以下假设变量 a 为 10,变量 b 为20:
运算符
描述
实例
==
等于 - 比较对象是否相等
(a == b) 返回 False。
!=
不等于 - 比较两个对象是否不相等
(a != b) 返回 True。
>
大于 - 返回x是否大于y
(a > b) 返回 False。
<
小于 - 返回x是否小于y。所有比较运算符返回1表示真,返回0表示假。这分别与特殊的变量True和False等价。
(a < b) 返回 True。
>=
大于等于 - 返回x是否大于等于y。
(a >= b) 返回 False。
<=
小于等于 - 返回x是否小于等于y。
(a <= b) 返回 True。
逻辑运算符 Python语言支持逻辑运算符,以下假设变量 a 为 10, b为 20:
运算符
逻辑表达式
描述
实例
and
x and y
布尔”与” - 如果 x 为 False,x and y 返回 x 的值,否则返回 y 的计算值。当第一个条件为False时,第二个条件不判断
(a and b) 返回 20。
or
x or y
布尔”或” - 如果 x 是 True,它返回 x 的值,否则它返回 y 的计算值。当第一个条件为True,第二个条件不再判断
(a or b) 返回 10。
not
not x
布尔”非” - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。
not(a and b) 返回 False
当数字不是0时,都表示True
赋值运算符 以下假设变量a为10,变量b为20:
运算符
描述
实例
=
简单的赋值运算符
c = a + b 将 a + b 的运算结果赋值为 c
+=
加法赋值运算符
c += a 等效于 c = c + a
-=
减法赋值运算符
c -= a 等效于 c = c - a
*=
乘法赋值运算符
c *= a 等效于 c = c * a
/=
除法赋值运算符
c /= a 等效于 c = c / a
%=
取模赋值运算符
c %= a 等效于 c = c % a
**=
幂赋值运算符
c * *= a 等效于 c = c ** a
//=
取整除赋值运算符
c //= a 等效于 c = c // a
:=
海象运算符,这个运算符的主要目的是在表达式中同时进行赋值和返回赋值的值。Python3.8 版本新增运算符 。
在这个示例中,赋值表达式可以避免调用 len() 两次:print(n:=10)
输出结果:10
成员运算符
运算符
描述
实例
in
如果在指定的序列中找到值返回 True,否则返回 False。
x 在 y 序列中 , 如果 x 在 y 序列中返回 True。
not in
如果在指定的序列中没有找到值返回 True,否则返回 False。
x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。
条件控制 if elif else
PYTHON
1 2 3 4 5 6 7 if condition_1: statement_block_1 elif condition_2: statement_block_2 else : statement_block_3
PYTHON
1 2 3 4 5 6 age = input ('输入你的年龄:' ) if int (age) >= 18 : print ("满18岁了可以去网吧" ) else : print ("未成年不能进入网吧" )
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 name = input ('输入你的用户名:' ) if name == 'admin' : print ("admin登录成功!" ) elif name == 'test' : print ("test登录成功!" ) else : print ("登陆失败!" ) name = input ('输入你的用户名:' ) if name == 'admin' or name == 'test' : print ("%s登陆成功!" % name) else : print ("登陆失败!" )
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 date = input ("输入今天是星期几:" ) if date == '1' : print ("今天要去上班" ) elif date == '2' : print ("才上了一天班呢" ) elif date == '3' : print ("到周中了" ) elif date == '4' : print ("今天是疯狂星期四" ) elif date == '5' : print ("明天就放假了!" ) elif date == '6' : print ("放假第一天" ) elif date == '7' : print ("明天就上班了" ) else : print ("你输入错误了" )
if嵌套
PYTHON
1 2 3 4 5 6 7 8 9 10 11 num = int (input ("请输入一个整数" )) if num % 2 == 0 : if num % 3 == 0 : print ("数字%d可以整除2和3" % num) else : print ("数字%d可以整除2,不能整除3" % num) else : if num % 3 == 0 : print ("数字%d可以整除3,不能整除2" % num) else : print ("数字%d既不能整除2也不能整除3" % num)
match…case
PYTHON
1 2 3 4 5 6 7 8 9 match subject: case <pattern_1>: <action_1> case <pattern_2>: <action_2> case <pattern_3>: <action_3> case _: <action_wildcard>
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def http_error (status ): match status: case 400 : return "Bad request" case 404 : return "Not found" case 418 : return "I'm a teapot" case 401 | 403 | 404 : return "Not allowed" case _: return "Something's wrong with the internet" mystatus=int (input ('输入状态码' )) print (http_error(mystatus))
猜拳游戏
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 import randomwhile True : player = input ("剪刀石头布,你出什么,想要退出输入0" ) if player == '0' : break randomid = random.randint(0 , 2 ) listcom = ['剪刀' , '石头' , '布' ] computer = listcom[randomid] match computer: case '剪刀' : print ("电脑出的是%s" % computer) print ("你出的是%s" % player) match player: case '剪刀' : print ("平局!" ) case '石头' : print ("你赢了!" ) case '布' : print ("你输了!" ) case _: print ("出错了!" ) case '石头' : print ("电脑出的是%s" % computer) print ("你出的是%s" % player) match player: case '剪刀' : print ("你输了!" ) case '石头' : print ("平局!" ) case '布' : print ("你赢了!" ) case _: print ("出错了!" ) case '布' : print ("电脑出的是%s" % computer) print ("你出的是%s" % player) match player: case '剪刀' : print ("你赢了!" ) case '石头' : print ("你输了!" ) case '布' : print ("平局!" ) case _: print ("出错了!" )
循环语句 while循环
PYTHON
1 2 while 判断条件(condition): 执行语句(statements)……
死循环和无限循环
死循环:bug造成的
无限循环:while true
,故意设计的。应用场景:书写循环时,不确定循环要执行多少次。无限循环的使用一般会在循环中添加if判断,当if条件成立,使用关键字break终止循环
while
1 2 3 4 5 6 7 8 # 1到100的数字之和 i = 1 sum = 0 while (i <= 100): sum = sum + i i = i + 1 print(sum)
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 i = 2 sum = 0 while (i <= 100 ): sum = sum + i i = i + 2 print (sum )i = 1 sum = 0 while (i <= 100 ): i = i + 1 if i % 2 == 0 : sum = sum + i print (sum )
while…else 如果 while 后面的条件语句为 false 时,则执行 else 的语句块。如果循环由break中断,不执行else中的语句
语法格式如下:
PYTHON
1 2 3 4 while <expr>: <statement(s)> else : <additional_statement(s)>
PYTHON
1 2 3 4 5 6 count = 0 while count < 5 : print (count, " 小于 5" ) count = count + 1 else : print (count, " 大于或等于 5" )
PYTHON
1 2 3 4 5 6 7 8 count = 0 while count < 5 : print (count, " 小于 5" ) count = count + 1 if count == 3 : break else : print (count, " 大于或等于 5" )
for循环 for 循环可以遍历容器中的数据,容器:字符串、列表、元组、字典
for循环的一般格式如下:
PYTHON
1 2 3 4 for <variable> in <sequence>: <statements> else : <statements>
for … in …
容器中有多少个数据,循环执行多少次
每次循环会将容器中的数据取出,保存到in前面的变量中
PYTHON
1 2 3 4 5 sites = ["Baidu" , "Google" , "chrome" , "Taobao" ] for site in sites: print (site)
PYTHON
1 2 3 4 5 word = 'Google' for letter in word: print (letter, end=' ' )
for … in range() 整数范围值可以配合 range() 函数使用:
PYTHON
1 2 for number in range (1 , 6 ): print (number,end='' )
PYTHON
1 2 3 4 5 6 7 for x in range (6 ): if x == 4 : break print (x, end=' ' ) else : print ("Finally finished!" )
for … else 在 Python 中,for…else 语句用于在循环结束后执行一段代码。
语法格式如下:
PYTHON
1 2 3 4 for item in iterable: else :
当循环执行完毕(即遍历完 iterable 中的所有元素)后,会执行 else 子句中的代码,如果在循环过程中遇到了 break 语句,则会中断循环,此时不会执行 else 子句。
PYTHON
1 2 3 4 for x in range (6 ): print (x,end=' ' ) else : print ("Finally finished!" )
PYTHON
1 2 3 4 5 6 7 for x in range (6 ): if x == 4 : break print (x, end=' ' ) else : print ("Finally finished!" )
range()函数
range() 函数会生成数列,range(n),可以生成0到n(不包含n)的数字。循环循环n次
range(a,b)生成从a到b(不含b)的数列
rang(a,b,c)c为步长(增量),可以为负数
PYTHON
1 2 3 4 5 list1 = ['hello' , 234 , 56 , 'wer' , 0 , 'wqqe' ] for i in range (len (list1)): print (i, list1[i])
还可以使用 range() 函数来创建一个列表
PYTHON
1 2 list (range (5 ))[0 , 1 , 2 , 3 , 4 ]
break和continue
break:终止循环,循环立即结束
continue:跳过本次循环,本次循环剩下的代码不再执行,进行下一次循环
break 语句可以跳出 for 和 while 的循环体。else 子句,它在穷尽列表(以for循环)或条件变为 false (以while循环)导致循环终止时被执行,如果从 for 或 while 循环中被break终止,任何对应的循环 else 块将不执行。
continue 语句被用来告诉 Python 跳过当前循环块中的剩余语句,然后继续进行下一轮循环。
PYTHON
1 2 3 4 5 6 7 8 9 str = input ("输入一个字符串并打印,当输入i的时候i不打印,当输入%的时候结束打印" )for i in str : if i == 'i' : continue if i == '%' : break print (i, end='' ) else : print ("打印完成!" )
pass语句 pass
是空语句,是为了保持程序结构的完整性。
pass
不做任何事情,一般用做占位语句
函数 函数的定义
PYTHON
1 2 3 4 5 6 7 def functname (): code ...
函数的调用
文档注释 本质上是注释,只是书写的位置和作用比较特殊
书写位置:在函数名的下方使用,三对双引号进行注释
作用:告诉别人函数如何使用
查看,在调用的时候,将光标放到函数名上使用ctrl+q
ctrl+b会转到函数的声明(按住ctrl鼠标左键点击)
函数的嵌套调用 在一个函数定义中调用另一个函数
注意:
函数定义不会调用函数体中的代码
函数调用会执行函数体中的代码
函数体中代码执行结束会回到函数被调用的地方继续向下执行
函数参数
在函数定义的时候,使用变量代替具体的数据(进行占位),称为形参,在调用函数的时候,传递具体的数值,称为实参
函数的传参传递的是引用
函数传参的方式 位置传参 在函数调用的时候,按照形参的顺序,将实参值传递给形参
关键字传参 在函数调用的时候,指定数据值给到那个形参
混合使用
关键字传参必须写在位置传参的后面
不能给一个形参传递多个数据
PYTHON
1 2 3 4 5 6 7 8 def my_sum (a, b ): return a + b num1 = int (input ('输入第一个数字' )) num2 = int (input ('输入第一个数字' )) print (my_sum(num1, num2))
缺省参数 缺省参数即默认参数
PYTHON
1 2 3 4 5 def functname (para1,para2='value' )
多值参数(不定长参数) 比如print()函数,可以有多个参数
在书写函数不确定参数个数的时候,可以使用不定长参数(多值参数)
不定长位置参数(不定长元组参数)
在普通参数的前面加上一个*
,这个参数就变为不定长位置参数
这个形参可以接受任意多个位置的传参
参数将被收集到一个元组中,并传递给函数
不定长位置参数写在普通参数的后面
一般写法,不定长位置参数的名字为args
,即(*args)
不定长关键字参数(不定长字典参数)
在普通参数的前面加上两个**
,这个参数就变为不定长关键字参数
这个形参可以接受任意多个关键字的传参
这些参数将被收集到一个字典中,并传递给函数。
不定长关键字参数写在所有参数的后面
一般写法,不定长关键字参数的名字为kwargs
,即(**kwargs)
PYTHON
1 2 3 4 5 6 7 8 9 10 11 def my_sum (*args, **kwargs ): num = 0 for i in args: num += i for j in kwargs.values(): num += j print (num) my_sum(1 , 2 , a=4 , b=5 , c=6 )
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def my_sum (*args, **kwargs ): num = 0 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 } my_sum(*mylist) my_sum(**mydict) my_sum(*mylist, **mydict)
完整的参数顺序
PYTHON
1 2 def functname (普通参数, *args, **kwargs): pass
PYTHON
1 2 3 4 5 6 7 8 9 10 11 def func (*args, **kwargs ): print (type (args), args) print (type (kwargs), kwargs) print ('-' * 30 ) func() func(1 , 2 , 3 ) func(a=1 , b=2 , c=3 ) func(1 , 2 , 3 , a=4 , b=5 , c=6 )
*在传参的作用 *
的作用是定义位置参数的结束和关键字参数的开始。当在函数定义中的参数列表中出现 *
时,它将标志着其前面的参数只能通过位置传递,而后面的参数只能通过关键字传递。
PYTHON
1 2 3 4 5 6 7 8 def func (a, b, *, d ): print (a, b, d) func(1 , 2 , d=3 ) func(1 , 2 , 3 )
函数的返回值 函数整体执行的结果,函数中得到的数据在后续的代码中还要使用,这时需要将数据作为返回值返回
return
之后的代码不会执行
PYTHON
1 2 3 4 5 6 def functname (): pass def functname (): return def functname (): return xx
变量 引用
变量和数据都是保存在内存中的。在 Python 中,变量是用来存储数据的标识符,它们也存储在计算机的内存中。Python 是一种动态类型语言,这意味着变量的类型是根据赋给它们的值来确定的,而不是在声明变量时显式地指定类型。
当我们在 Python 中创建变量并给它们赋值时,Python 解释器会在内存中分配一块空间来存储这些变量的值。每个变量都有一个名称(标识符)和一个关联的内存地址,我们可以使用这个名称来访问和操作变量的值。
变量存储的是对象的引用(对象的内存地址)
在python中函数的参数传递以及返回值都是靠引用传递的
1 2 3 4 5 6 1. 在定义变量的时候 变量=数据值,Python解释器会在内存中开辟两块空间 2. 变量和数据都有自己的空间 3. 本质:数据的地址保存到变量对应的内存中 4. 变量中储存数据地址的行为就是引用(变量引用了数据的地址,简单说就是变量中储存了数据)存储的地址称为引用地址 5. 可以使用id(),获取变量中的引用地址,即数据的地址。如果两个变量的id()获取的引用地址一样,代表着两个变量引用了同一个数据 6. 只有赋值运算符=可以改变变量的引用
PYTHON
1 2 3 4 5 6 7 a = 1 b = 2 c = 1 print (id (a))print (id (b))print (id (c))
可变类型和不可变类型
1 2 3 4 5 6 数据类型:int float bool str list tuple dict set 可变类型:数据所在的内存允许修改 不可变类型:数据所在的内存不允许修改 不使用=,变量引用的数据中的内容是否会变化,会变化是可变的,不会变化是不可变的。比方list可以用append()方法进行修改 可变类型:list,dict,set 不可变类型:int,float,bool,str,tuple
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 list1=[1 ,2 ,3 ] print ('list1' ,id (list1))list2=[1 ,2 ,3 ] print ('list2' ,id (list2))print ('list1[0]' ,id (list1[0 ]))print ('list1[1]' ,id (list1[1 ]))print ('list1[2]' ,id (list1[2 ]))print ('list2[0]' ,id (list2[0 ]))print ('list2[1]' ,id (list2[1 ]))print ('list2[2]' ,id (list2[2 ]))list1[1 ]=10 print ('list1' ,id (list1))print ('list1[0]' ,id (list1[0 ]))print ('list1[1]' ,id (list1[1 ]))print ('list1[2]' ,id (list1[2 ]))
PYTHON
1 2 3 4 5 6 7 mytuple = (1 , 2 , [3 , 4 ]) print (id (mytuple[-1 ]))mytuple[-1 ][0 ] = 10 print (mytuple)print (id (mytuple[-1 ]))
交换两个变量的值
PYTHON
1 2 3 4 5 6 7 8 a = 10 b = 20 a = a + b b = a - b a = a - b a, b = b, a
组包(pack)和拆包(unpack)
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 a = 10 b = 20 c = a, b print ('组包结果:' , type (c), c)a, b = c print ('拆包结果是' , a, b)x, y, z = [1 , 2 , 3 ] print (x, y, z)
局部变量和全局变量
局部变量 在函数内部定义的变量,称为局部变量。形参属于局部变量
特点:
局部变量只能在当前函数内部使用,不能在其他函数和函数外部使用
在不同函数中,可以定义名字相同的局部变量,两者之间没有明显
局部变量生存周期(生命周期,作用范围):在函数被调用的时候,局部变量被创建;函数调用结束,局部变量的值被销毁,不能使用
函数局部变量的值想要被函数外部使用,需要使用return
关键字
全局变量 在函数外部定义的变量,称为全局变量
特点:
可以在任何函数中读取全局变量的值
如果在函数中存在和全局变量名字相同的局部变量,在函数中使用的是局部变量的值(就近原则)
在函数内部想要修改全局变量的引用(数据值),需要添加global
关键字对变量进行声明为全局变量。类似列表的.append()
操作不改变引用不需要globa
的操作(引用传递)
代码执行的时候全局变量被创建,代码执行结束全局变量被销毁
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 num=10 def func1 (): print (num) def func2 (): num=20 print (num) def func3 (): global num num=30 print (num) func1() func2() func3() func1()
函数返回值
匿名函数(lambda表达式) Python 使用 lambda 来创建匿名函数。
lambda 函数是一种小型、匿名的、内联函数,它可以具有任意数量的参数,但只能有一个表达式。
匿名函数不需要使用 def 关键字定义完整函数。
lambda 函数通常用于编写简单的、单行的函数,通常在需要函数作为参数传递的情况下使用 ,例如在 map()
、filter()
、reduce()
等函数中。
lambda 函数特点:
lambda 函数是匿名的,它们没有函数名称,只能通过赋值给变量或作为参数传递给其他函数来使用。返回值不需要return
,一行代码(表达式)的结果就是返回值
lambda 函数通常只包含一行代码,这使得它们适用于编写简单的函数。
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 def func1 (): print ('hello world' ) func1() a = lambda : print ('hello lambda' ) a() def func2 (): return 10 print (func2())b = lambda : 22 print (b())def mysum (a, b ): print (a + b) mysum(1 , 2 ) c = lambda a, b: print (a + b) c(10 , 22 ) def sum1 (a, b ): return a + b print (sum1(2 , 4 ))d = lambda a, b: a + b print (d(5 , 6 ))
PYTHON
1 2 3 4 5 6 7 b = lambda x: x.get('age' ) print (b({'name' : 'ann' , 'age' : 18 }))
匿名函数作为参数 列表中的字典排序 sort()
方法会原地修改列表,而不是返回一个新的排序后的列表。该方法有两个可选参数:key
和 reverse
。
key
参数是一个函数,用于指定排序的比较方式。默认情况下,sort()
方法会按照列表元素的大小进行排序。如果指定了 key
参数,sort()
方法会使用该函数的返回值来比较元素,从而进行排序。
reverse
参数是一个布尔值,用于指定排序的顺序。默认情况下,reverse=False
,即升序排序。如果设置为 True
,则会进行降序排序。
对字典来说,比大小需要使用sort()
中的key参数。key参数需要传递一个函数,一般是匿名函数。
字典的排序需要指定依照字典的什么键进行排序,需要使用匿名函数返回字典的键对应的值
PYTHON
1 2 3 4 5 6 user_list = [{'name' : 'lisi' , 'age' : 18 }, {'name' : 'zhangsan' , 'age' : 19 }, {'name' : 'wangwu' , 'age' : 17 }] user_list.sort(key=lambda x: x.get('name' ), reverse=True ) print (user_list)user_list.sort(key=lambda x: x.get('age' ), reverse=True ) print (user_list)
ord()
可以获取字符对应的ASCII码
chr(ASCII)
可以获取ASCII码对应的字符
面向对象 面向对象是一种编程思想
类和对象
类
多个特征和行为相同或相似事物的统称
泛指的(指代多个,而不是一个)
对象
具体存在的一个事物,看得见摸得着的
特指的(指一个)
由类创建的
1 2 3 苹果 ----->类 红苹果 ----->类 张三嘴里吃的苹果 ---->对象
类的组成
类名:给多个事物起的名称,在代码中要满足大驼峰命名法
属性:事物的特征
方法:事物的行为,类中定义的函数。
类的抽象(类的设计):找到类的类名,属性和方法
1 2 3 4 5 6 7 8 9 10 1. 小明 今年18岁,身高1.75,每天早上跑完步会去吃东西 2. 小红 今年17岁,身高1.72,不跑步,喜欢吃吃东西 类名:人类(Person) 属性:名字(name)、年龄(age)、身高(height) 方法:跑步(run)、吃(eat) 一只黄颜色的狗狗叫大黄,看见生人汪汪叫,看见熟人摇尾巴 类名:狗类(dog) 属性:颜色(color)、名字(name) 方法:汪汪叫(bark),摇尾巴(shake)
对象 python中一切都是对象,即用class
定义的类也是对象
属性:对对象的特征的描述
方法:对象具有的行为
对象的划分 实例对象(实例) 通过类名()
创建的对象即实例对象,简称实例
创建对象的过程称作类的实例化
我们平时说的对象就是实例对象
每个实例都有自己的内存空间,在自己的内存空间中保存自己的属性(实例属性)
类对象(类名) 类对象就是类,可以认为是类名(类名包含了整个类)
在 Python 中,类也是对象。更具体地说,类是一个类型对象,它是由 type
类创建的实例。因此,类对象就是一个实例化了 type
类的对象。
类对象是python解释器在执行代码的过程中创建的
类对象的作用:使用类对象创建实例,类对象也有自己的内存空间,可以保存一些属性值(类属性)信息
在一个代码中,一个类只有一份内存空间
属性的划分 实例属性 概念:是实例对象具有的属性
定义和使用:
在__init__
方法中,使用self.属性名= 属性值
定义
在方法中使用self.属性名
来调用
在每个实例当中都存在一份内存空间
使用时机:基本上99%都是实例属性,通过self
定义。多个对象判断这个值是不是一样的,如果都是一样的,同时变化,一般定义为类属性,否则定义为实例属性
类属性 概念:是类对象具有的属性
定义和使用:
在类内部,方法外部定义的变量
类对象.属性名=属性值
或类名.属性名=属性值
使用类对象.属性名
或类名.属性名
调用
只有类对象中存在一份内存空间
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Dog : count = 0 def __init__ (self, name ): self.name = name; Dog.count += 1 dog1 = Dog('小花' ) print (Dog.count)dog2 = Dog('大黄' ) print (Dog.count)dog2 = Dog('小白' ) print (Dog.count)print (dog1.count)print (dog2.count)print (dog3.count)
方法的划分 实例方法(最常用)
类方法
定义:在方法名字的上方书写@classmethod
装饰器
PYTHON
1 2 3 4 class Demo : @classmethod def func (cls ): pass
定义时机:方法中不需要使用实例属性(即self),用到了类属性,可以将这个方法定义为类方法,也可以定义为实例方法
调用:通过类对象调用:类名.方法名()
,通过实例对象调用:实例.方法名()
静态方法
定义:在方法名字的上方书写@staticmethod 装饰器
PYTHON
1 2 3 4 class Demo : @staticmethod def func (): pass
使用时机:方法中不需要使用实例属性,也不使用类属性,可以将这个方法定义为静态方法
调用:通过类对象调用:类名.方法名()
,通过实例对象调用:实例.方法名()
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 import randomclass Game : top_score = 0 def __init__ (self, name ): self.name = name @classmethod def start_game (cls ): cls.score = random.randint(10 , 100 ) print (f'本次游戏得分{cls.score} ' ) @classmethod def show_top_score (cls ): if cls.score > Game.top_score: Game.top_score = cls.score print (f'现在的最高分是{Game.top_score} ' ) else : print (f'现在的最高分是{Game.top_score} ' ) @staticmethod def show_help (): print ("这场游戏的得分都是随机的" ) player1 = Game('小王' ) player1.start_game() Game.show_top_score() player1.start_game() Game.show_top_score() Game.show_help()
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 import randomclass Game : top_score = 0 top_score_player='' def __init__ (self, name ): self.name = name self.score = 0 def start_game (self ): self.score = random.randint(10 , 100 ) print (f'本次{self.name} 游戏得分{self.score} ' ) def show_top_score (self ): if self.score > Game.top_score: Game.top_score = self.score Game.top_score_player = self.name print (f'现在的最高分是{Game.top_score} ,得主是{Game.top_score_player} ' ) else : print (f'现在的最高分是{Game.top_score} ,得主是{Game.top_score_player} ' ) @staticmethod def show_help (): print ("这场游戏的得分都是随机的" ) player1 = Game('小王' ) player1.start_game() player1.show_top_score() player2 = Game('小李' ) player2.start_game() player2.show_top_score() player3 = Game('小张' ) player3.start_game() player3.show_top_score() player4 = Game('小红' ) player4.start_game() player4.show_top_score() Game.show_help()
面向对象的代码步骤
定义类,在定义类之前先设计类
先定义简单的类,不包含属性,在python中定义类需要使用关键字class
方法:在类中定义的函数,第一个参数是self
(实例方法)
PYTHON
1 2 3 class 类名 : def 方法名 (self ): pass
创建对象,使用第一步定义的类创建对象
创建对象使用类名()
进行创建
通过对象调用方法
对象.方法名()
案例实现
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Cat : def eat (self ): print ("小猫爱吃鱼" ) def drink (self ): print ("小猫要喝水" ) bluecat = Cat() bluecat.eat() bluecat.drink() redcat = Cat() redcat.eat() redcat.drink()
self的说明
PYTHON
1 2 3 class Cat : def eat (self ): print ("小猫爱吃鱼" )
从函数的语法上讲,self
是形参,就可以是任意的变量名,只不过我们习惯性将这个形参写成self
self
是普通的形参,但是调用的时候没有传递实参值,原因是python解释器在执行代码的时候,自动**调用这个方法的对象传递给了self
**,即self
的本质是对象
只需要确定通过哪个对象调用,对象的引用和self
的引用一样
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Cat : def eat (self ): print (f'{id (self)} ,self' ) print ("小猫爱吃鱼" ) bluecat = Cat() bluecat.eat() print (id (bluecat), 'bluecat' )a = bluecat a.eat() print (id (a), 'a' )redcat = Cat() redcat.eat() print (id (redcat), 'redcat' )
每次创建对象会开辟新的内存空间
对象的属性操作 添加属性 对象.属性名 = 属性值
类内部添加
1 2 self.属性名 = 属性值 # 在类中添加属性一般写在__init__方法中
类外部添加
魔法方法 python中有一类方法,以两个下划线开头,两个下划线结尾,并且在满足某个条件的情况下会自动调用 ,这类方法称为魔法方法
__init__方法
创建对象后会自动调用
应用场景:给对象添加属性的(初始方法,构造方法)。某些代码,在每次创建对象后都要执行,可以写在__init__
方法中
如果__init__
函数有除了self
之外的参数,要记得传参
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Cat : def __init__ (self ): self.name = '蓝猫' self.age = 2 print ("我是__init__,我被调用了" ) def show_info (self ): print (f'小猫的名字是{self.name} ,年龄是{self.age} ' ) Cat() bluecat = Cat() a = bluecat bluecat.show_info()
带参数的_init _:
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Cat : def __init__ (self, name, age ): self.name = name self.age = age print ("我是__init__,我被调用了" ) def show_info (self ): print (f'小猫的名字是{self.name} ,年龄是{self.age} ' ) bluecat = Cat('蓝猫' , 2 ) bluecat.show_info() redcat = Cat('红猫' , 3 ) redcat.show_info()
__str__方法
使用print()
打印对象后会自动调用
应用场景:在这个方法中一般书写对象的属性信息,即打印对象的时候想要查看的信息在此方法中定义。如果类中没有定义此方法,print(对象)
输出对象的引用地址
这个方法必须返回一个字符串
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Cat : def __init__ (self, name, age ): self.name = name self.age = age def __str__ (self ): return f'小猫的名字是{self.name} ,年龄是{self.age} ' bluecat = Cat('蓝猫' , 2 ) print (bluecat)redcat = Cat('红猫' , 3 ) print (redcat)
__del__方法 __del__
方法(析构方法),对象被删除销毁时,自动调用。一种是程序运行结束,所有对象被销毁;一种是使用del
删除对象(如果对象有多个名字即多个变量引用同个对象,需要把所有的对象都删除)
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Demo : def __init__ (self, name ): print ('__init__被调用了' ) self.name = name def __del__ (self ): print (f'{self.name} 没了' ) a = Demo('a' ) b = Demo('b' ) c = Demo('c' ) del aprint ('代码运行结束' )
小明跑步
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 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} 跑了5km,体重减少了' ) self.weight -= 0.5 def eat (self ): print (f'{self.name} 大餐一顿,体重增加了' ) self.weight += 1.0 xm = Person('小明' , 75.0 ) print (xm) xm.run() print (xm) xm.eat() print (xm)
摆放家具
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 class House : def __init__ (self, housetype, square ): self.housetype = housetype self.square = square self.leftsquare = square self.furniture = [] def __str__ (self ): return (f'房子的户型是{self.housetype} ,房子的总面积是{self.square} 平方米,' f'房子的剩余面积是{self.leftsquare} 平方米,家具有{self.furniture} ' ) def add_item (self, item ): if self.leftsquare > item.square: self.furniture.append(item.name) self.leftsquare -= item.square else : print ('剩余面积不够了!添加失败!' ) class HouseItem : def __init__ (self, name, square ): self.name = name self.square = square def __str__ (self ): return f'家具是{self.name} ,占据面积是{self.square} 平方米' bed = HouseItem('席梦思' , 4 ) print (bed)chest = HouseItem('衣柜' , 2 ) print (chest)table = HouseItem('餐桌' , 1.5 ) print (table)newhouse = House('一室一厅' , 98 ) newhouse.add_item(bed) print (newhouse)newhouse.add_item(bed) print (newhouse)newhouse.add_item(chest) print (newhouse)newhouse.add_item(table) print (newhouse)
登录案例
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class LoginPage : def __init__ (self, username, password, code ): self.name = username self.password = password self.code = code self.btn = '登录' def login (self ): print (f'1. 输入用户名{self.name} ' ) print (f'2. 输入密码{self.password} ' ) print (f'3. 输入验证码{self.code} ' ) print (f'4. 点击按钮{self.btn} ' ) login = LoginPage('admin' , '123456' , '8888' ) login.login()
获取属性 对象.属性名
类内部添加:self.属性名
类外部添加:对象.属性名
,一般很少使用
给对象进行属性添加后,对象内存地址不变
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Cat : def eat (self ): print (f'{id (self)} ,self' ) print (f"小猫{self.name} 爱吃鱼" ) bluecat = Cat() print (f'{id (bluecat)} ,bluecat' )bluecat.name = '蓝猫' bluecat.eat() redcat = Cat() print (f'{id (redcat)} ,redcat' )redcat.name = '红猫' redcat.eat()
私有和公有 在Python中定义的方法和属性,可以添加访问控制权限(即在什么地方可以使用这个属性和方法)
公有权限
直接书写的方法和属性都是公有的
公有的方法和属性可以在任意地方访问和使用
私有权限
在类内部,属性名或者方法名前面加上两个下划线__
,就变为私有
私有方法和属性只能在当前类内部使用
在类外部操作私有属性,在类内部定义公有方法去操作私有属性
什么时候定义私有?
某个属性或者方法不写在类外部被访问和使用,将其定义为私有
测试中一般不怎么使用,直接公有
开发中根据需求文档去确定什么作为私有
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Person : def __init__ (self, name, age ): self.name = name self.__age = age def __str__ (self ): return f'名字:{self.name} ,年龄{self.__age} ' xm = Person('小明' , 18 ) print (xm)print (xm.__age)
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Person : def __init__ (self, name, age ): self.name = name self.__age = age def __str__ (self ): return f'名字:{self.name} ,年龄{self.__age} ' xm = Person('小明' , 18 ) print (xm)xm.__age = 20 print (xm)print (xm._Person__age)xm._Person__age=19 print (xm._Person__age)
__dict__魔法属性 可以将对象具有的属性组成字典返回
PYTHON
1 2 3 4 5 xm = Person('小明' , 18 ) print (xm.__dict__)xm.__age = 20 print (xm.__dict__)
继承 继承描述的是类与类之间的关系,可以减少代码的冗余,实现代码的重用。
子类继承父类之后,子类的对象可以直接使用父类中定义的公有属性和方法。
单继承:一个类只继承一个父类
PYTHON
1 2 3 4 5 6 class 类名 (父类名 ): pass class A : pass class B (A ): pass
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Animal : def eat (self ): print ('哐哐吃' ) class Dog (Animal ): def bark (self ): print ('汪汪叫' ) class XiaoTianQuan (Dog ): pass ani = Animal() ani.eat() dog = Dog() dog.eat() dog.bark() xiaotian = XiaoTianQuan() xiaotian.eat() xiaotian.bark()
重写 在子类中定义了和父类中名字相同的方法就是重写。
当父类中的方法不能满足子类对象的需求,所以重写。
重写之后,调用子类自己的方法,不调用父类中的方法
重写的方式
多态 不同类的对象对相同的方法做出不同的响应。简单来说,多态性使得能够以统一的方式使用不同类型的对象,而不必关心它们具体的类型。
多态性使得我们可以编写更加灵活和通用的代码,因为我们不需要关心对象的具体类型,只需要知道它们共享相同的接口(即方法),就可以以统一的方式对待它们。
文件 文件通常是以字节序列的形式存储在存储设备(如硬盘、固态硬盘、闪存驱动器等)上的。
文本文件:能使用记事本软件打开,能使用记事本转换为文字。txt、md、py
二进制文件:不能使用记事本打开的。exe、mp3、mp4、png、jpg
文件操作的步骤 打开文件 将文件从磁盘中读取到内存中(CPU只能对内存执行操作)
文件流一般写入try中,因为文件流容易报错
PYTHON
1 2 3 4 5 6 7 8 9 10 open (file,mode='r' ,encoding=None )> 参数file:打开的文件,类型是字符串,文件路径可以是相对路径(推荐),也可以是绝对路径 > 参数mode:默认参数(缺省参数),表示打开文件的方式 > r:read 只读打开 > w:write 只写打开 > a:append 追加打开,在文件的末尾写入内容 > 参数encoding:编码方式,文字和二进制如何转换 >gbk:将一个汉字转换为两个字节二进制 >utf-8 :将一个汉字转换为三个字节二进制 > 返回值:返回的是文件对象,后续对文件的操作都需要这个对象
读写文件 写文件 向文件中写入指定的内容。
前提:文件的打开方式是 w 或者 a
PYTHON
1 2 3 4 5 6 7 8 文件对象.write('写入文件的内容' ) 1. 文件不存在会直接创建2. 文件存在会覆盖原文件1. 文件不存在会直接创建2. 文件存在会在末尾写入内容
PYTHON
1 2 3 f = open ('a.txt' , 'w' , encoding='utf-8' ) f.write('good good' ) f.close()
读文件 将文件中的内容读取出来
前提:文件的打开方式是 r
PYTHON
1 2 3 4 f = open ('a.txt' , 'r' , encoding='utf-8' ) buf = f.read() print (buf)f.close()
关闭文件
PYTHON
1 2 关闭文件:将文件占用的资源进行清理,同时会保存文件,文件关闭之后这个文件对象就不能使用了 文件对象.close()
with open打开文件 好处:不用自己去书写关闭文件的代码,会自动进行关闭
PYTHON
1 2 3 with open (file, mode, encoding='utf-8' ) as 变量:
PY
1 2 with open ('a.txt' , 'a' , encoding='utf-8' ) as f: f.write('day day up' )
按行读取 一次读取一行内容,文件对象.readline()
PYTHON
1 2 3 4 with open ('a.txt' , encoding='utf-8' ) as f: buf=f.readline() print (buf) print (f.readline())
PYTHON
1 2 3 4 5 6 7 8 9 10 11 with open ('a.txt' , encoding='utf-8' ) as f: for i in f: print (i, end='' ) with open ('a.txt' , encoding='utf-8' ) as f: while True : buf = f.readline() if len (buf) == 0 : break else : print (buf,end='' )
json文件 json=’java script object notation’,是JavaScript对象表示法,是一种基于文本,独立于语言的轻量级数据交换格式 。
基于文本:是一个文本文件,不能包含图片,音视频等
独立于语言:不是某个语言特有的,每种编程语言都可以使用
轻量级:相同的数据和其他格式相比占用的大小比较小
数据交换格式:后端程序员给前端的数据(json,html,xml)
json文件也是一种文本文件,可以直接使用read()
和write()
操作,但是不方便。json文件有独特的读取和写入方法
常用在做测试的时候,将测试数据定义为json文件格式,使用代码读取json文件,即读取测试数据,进行传参(参数化)
json语法规则
json文件的后缀是.json
json文件中的主要数据类型是对象({}类似Python中的字典)和数组([]类似列表),对象和数组可以互相嵌套
一个json文件是一个对象或者数组,即json文件的最外层要么是一个大括号{},要么是一个数组[]
json中的对象是由键值对组成的,每个数据之间使用,隔开,但是最后一个数据后面不要写逗号
json中的字符串必须使用””双引号
json中的其他数据类型:数字类型(int float)、字符串string(str)、布尔类型(true、false)、None(null)
JSON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 { "name" : "小明" , "age" : 18 , "gender" : 1 , "isFan" : true , "hobbies" : [ "听歌" , "游戏" , "购物" , "睡觉" ] , "address" : { "country" : "China" , "city" : "Shanghai" } }
读取json文件
1 2 3 4 5 1. 导包 import jason 2. 读打开文件 3. 读文件 json.load(文件对象) # 返回的是字典(对象)或者列表(数组)
PYTHON
1 2 3 4 5 6 7 8 9 10 11 import jsonwith open ('info.json' , encoding='utf-8' ) as f: result = json.load(f) print (type (result)) print (result.get('name' )) print (result.get('age' )) print (result.get('address' ).get('city' ))
JSON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 [ { "name" : "小明" , "age" : 18 , "gender" : 1 , "isFan" : true , "hobbies" : [ "听歌" , "游戏" , "购物" , "睡觉" ] , "address" : { "country" : "China" , "city" : "Shanghai" } } , { "name" : "小红" , "age" : 17 , "gender" : 0 , "isFan" : false , "hobbies" : [ "听歌" , "学习" , "购物" , "睡觉" ] , "address" : { "country" : "China" , "city" : "Beijing" } } ]
PYTHON
1 2 3 4 5 6 7 8 with open ('info.json' , encoding='utf-8' ) as f: result = json.load(f) print (type (result)) for info in result: print (info.get('name' ), info.get('age' ), info.get('address' ).get('city' ))
测试读取案例
JSON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 [ { "desc" : "正确的用户名密码" , "username" : "admin" , "password" : "123456" , "expect" : "登录成功" } , { "desc" : "错误的用户名" , "username" : "root" , "password" : "123456" , "expect" : "登录失败" } , { "desc" : "错误的密码" , "username" : "admin" , "password" : "123123" , "expect" : "登录失败" } , { "desc" : "错误的用户名和密码" , "username" : "aaa" , "password" : "123123" , "expect" : "登录失败" } ]
PYTHON
1 2 3 4 5 6 7 8 9 10 with open ('test.json' , encoding='utf-8' ) as f: result = json.load(f) test_list = [] for info in result: test_tuple = (info.get('username' ), info.get('password' ), info.get('expect' )) test_list.append(test_tuple) print (test_list)
json的写入 文件对象.write(字符串)
不能直接将python的列表和字典作为参数传递。想要将python中的数据类型存为json文件,需要使用json提供的方法,不再使用write
1 2 3 4 1. 导包 import json 2. 写(w)方式打开文件 3. 写入 json.dump(python中的数据类型,文件对象)
PYTHON
1 2 3 4 5 6 7 8 9 import jsonmy_list = [('admin' , '123456' , '登录成功' ), ('root' , '123456' , '登录失败' ), ('admin' , '123123' , '登录失败' ), ('aaa' , '123123' , '登录失败' )] with open ('info1.json' , 'w' , encoding='utf-8' ) as f: json.dump(my_list, f, ensure_ascii=False ,indent=2 )
PYTHON
1 2 3 def dump (obj, fp, *, skipkeys=False , ensure_ascii=True , check_circular=True , allow_nan=True , cls=None , indent=None , separators=None , default=None , sort_keys=False , **kw )
函数参数列表里,*后面的参数只能以关键字的形式传参,不能使用位置传参
异常 程序运行时,python解释器遇到一个错误,会停止程序的执行,并且提示一些错误信息,这就是异常。
程序停止执行并且提示错误信息,这个动作是抛出异常(raise
)。程序遇到异常,默认动作是终止代码程序的执行。捕获异常可以使代码继续执行,不会终止运行
异常捕获
PYTHON
1 2 3 4 5 6 7 8 9 try : 可能发生异常的代码 except : 发生了异常执行的代码 try : 可能发生异常的代码 except 异常类型: 发生了异常执行的代码
PYTHON
1 2 3 4 5 6 7 8 while True : try : num=input ('请输入数字' ) num=int (num) print (num) except : print ('请输入正确数字' ) print ('后续代码仍然运行' )
可以针对不同的异常错误,运行单独的代码处理
PYTHON
1 2 3 4 5 6 7 8 9 10 11 try : 可能发生的异常的代码 except 异常类型1 : 发生异常类型1 执行的代码 except Exception as 变量: 发生其他类型的异常,执行的代码 else : 没有发生异常执行的代码 finally : 不论如何都会执行的代码
PYTHON
1 2 3 4 try : 可能发生的异常的代码 except Exception as e: 发生异常执行的代码
PYTHON
1 2 3 4 5 6 7 8 9 10 try : num=input ('请输入数字' ) num=int (num) num=20 /num print (num) except ValueError: print ('发生了异常,请输入正确数字' ) except ZeroDivisionError: print ('不要输入0' )
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 while True : try : num=input ('请输入数字' ) num=int (num) num=20 /num print (num) except Exception as e: print (f'错误信息为:{e} ' ) else : print ("没有发生异常" ) finally : print ('我都会执行' )
异常传递 python会将异常进行传递。在函数嵌套调用的过程中,被调用的函数发生了异常,如果没有捕获,会将这个异常向外层传递。如果传到最外层还没有捕获,才报错。
抛出异常raise 让代码报错
模块和包 模块(Module)是一个包含 Python 代码的文件。这些文件通常包含了一些函数、类和变量的定义,可以被其他 Python 程序导入并使用。模块使得代码的组织和管理更加方便,同时也可以提高代码的可重用性。
模块名同样也是一个标识符,需要符合标识符的命名规则
在模块中定义的全局变量、函数、类都是提供给外界直接使用的工具
模块就好比是工具包,要使用这个工具包的工具需要先导入这个模块
自己写的代码想要作为模块使用,代码的名字需要满足标识符的规则
模块的导入 import导入 使用模块中的内容:模块名.工具名
PYTHON
1 2 3 4 5 6 7 8 9 import 模块1 名,模块2 名模块名.工具名 import randomimport jsonrandom.randint(a,b) json.load json.dump
PYTHON
1 2 3 4 5 6 7 8 9 from 模块名 import 工具名工具名 from random import randintfrom json import load,dumprandint(a, b) load() dump()
PYTHON
1 2 3 4 5 6 7 8 from 模块名 import * from random import *from json import *randint(a, b) load() dump()
对于导入的模块和工具可以使用as
起别名,如果起别名,原来的名字就不能使用了
模块的查找顺序 在导入模块的时候,会先在当前目录中找模块,如果找到,就直接使用。如果没有找到,就回去系统的目录中进行查找,找到就直接使用,没有找到会报错
注意:在定义代码文件的时候,代码名字不能和要导入的模块名字相同,会造成混淆产生命名冲突,Python 解释器会优先使用当前目录下的同名文件,而不是标准库或其他模块中的同名模块。
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 def func (): print ('我是tools模块中的func方法' ) class Dog : def __init__ (self, name, age ): self.name = name self.age = age def play (self ): print (f'{self.name} 在快乐的玩耍' ) import toolstools.func() dog1 = tools.Dog('大黄' , 3 ) dog1.play()
__name__作用 每个代码文件都是一个模块,在导入模块的时候,会执行模块中的方法。
__name__
变量:
是python解释器自动维护的变量
__name__
变量,如果代码直接运行,值是"__main__"
__name__
变量,如果代码是被导入运行,值是模块名(代码名)
包package 包(Package)是一种包含多个模块的目录结构。通常情况下,包是一个目录,包含了一个特殊的 __init__.py
文件和多个模块文件。__init__.py
文件可以为空,也可以包含一些初始化代码。包可以嵌套,即一个包可以包含其他包。
在python使用的时候不需要可以区分是包还是模块,因为使用方式是一样的
random
是一个模块json
是一个包
UnitTest框架 是python中自带的单元测试框架。pytest是第三方框架,需要安装。
对于开发来说,单元测试框架主要用来做单元测试。对测试来说,unittest框架的作用是自动化脚本(用例代码)执行框架,管理运行多个测试用例
为什么使用UnitTest框架?
能够组织多个用例去执行
提供丰富的断言方法(让程序代码替人工自动的判断预期结果和实际结果是否相符)
能够生成测试报告
UnitTest核心(组成)
TestCase(最核心的模块)
unittest.TestCase
类是编写测试用例的基础。你可以通过创建继承自 TestCase
的子类,并在子类中定义测试方法来编写测试用例。每个测试方法都应该以 test_
开头,这样 unittest 才能识别它们并执行。
TestSuite
测试套件是一组测试用例的集合。你可以使用 unittest.TestSuite
类来创建一个测试套件,并将多个测试用例添加到这个套件中。这样可以方便地对多个测试用例进行组织和管理。
TestRunner
测试运行器负责执行测试套件中的测试用例,并生成测试报告。unittest 提供了命令行接口和 GUI 工具来运行测试,并且可以生成详细的测试报告,包括测试结果、运行时间、覆盖率等信息。
TestLoader
TestLoader(测试加载),对TestSuite(测试套件)功能的补充。自动搜索加载的一种方式,从指定的模块或目录中加载测试用例,并根据一定的规则将它们组织成测试套件。它可以自动发现符合命名规范的测试用例,并将它们添加到测试套件中,以便后续执行。
Fixture
Fixture(测试夹具),书写在TestCase代码中,是一个代码结构,可以在每个方法执行前后都会执行的内容(前置代码)。unittest 提供了 setUp()
和 tearDown()
方法,它们分别在每个测试方法执行前后自动调用,用于准备测试环境和清理测试
TestCase(测试用例) 在这个代码文件中书写真正的用例代码,代码文件的名字必须按照标识符的规则来书写
步骤:
导包(unittest)
自定义测试类,新建测试类必须继承unittest.TestCase 。运行的时候主模块是TestCase
在测试类中书写测试方法,测试方法名称必须以test_开头 。
执行用例
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 """ 学习TestCase模块的书写方法 """ import unittestclass TestDemo (unittest.TestCase): def test_method1 (self ): print ('测试方法1' ) def test_method2 (self ): print ('测试方法2' )
TestSuite&TestRunner TestSuite(测试套件):管理、打包、组装TestCase(测试用例)文件
TestRunner(测试执行,测试运行):执行TestSuite(测试套件)
步骤:
导包(unittest)
实例化(创建对象)套件对象
使用套件对象添加用例方法
实例化运行对象
使用运行对象去执行套件对象
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 """ 用来学习testsuite和testrunner """ import unittestfrom day1.testcase1 import TestDemo1from day1.testcase2 import TestDemo2suite=unittest.TestSuite() suite.addTest(TestDemo1('test_method1' )) suite.addTest(TestDemo1('test_method2' )) suite.addTest(TestDemo2('test_method1' )) suite.addTest(TestDemo2('test_method2' )) suite.addTest(unittest.makeSuite(ClassName)) runner=unittest.TextTestRunner() runner.run(suite)
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 """ 用来学习testsuite和testrunner """ import unittestfrom day1.testcase1 import TestDemo1from day1.testcase2 import TestDemo2suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestDemo1)) suite.addTest(unittest.makeSuite(TestDemo2)) runner = unittest.TextTestRunner() runner.run(suite)
运行结果中的。表示用例通过,F表示用例不通过(运行结果和预期结果不符合),E代表用例代码有问题。
makeSuite()
要被python官方弃用!!
TestLoader(测试加载) TestLoader(测试加载)和TestSuite作用是一样的,对TestSuite功能的补充,用来组装测试用例。如果TestCase的代码文件有很多,可以使用TestLoader
步骤
导包
实例化测试加载对象并添加用例,得到的是Suite对象
实例化运行对象
运行对象执行套件对象
在一个项目中TestCase的代码一般放在一个单独的目录(case)
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 import unittestsuite = unittest.TestLoader().discover('./case' , '*.py' ) runner = unittest.TextTestRunner() runner.run(suite)
TestLoader与TestSuite区别
TestSuite需要手动添加测试用例(可以添加测试类,也可以添加测试类中的某个方法
TestLoader搜索指定目录下指定开头.py文件并添加测试类中的以test开头的所有的测试方法,不能指定添加方法
makeSuite()
方法要被弃用,可以使用TestLoader
添加用例
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import unittestclass MyTestCase (unittest.TestCase): def test_case1 (self ): self.assertEqual(1 + 1 , 2 ) def test_case2 (self ): self.assertTrue(True ) def test_case3 (self ): self.assertFalse(False ) suite = unittest.TestLoader().loadTestsFromTestCase(MyTestCase) runner = unittest.TextTestRunner() runner.run(suite)
Fixture(测试夹具) 是一个概述,对一个测试用例环境的初始化和销毁就是一个Fixture。在某些特点的情况下会自动去执行
方法级别 写在方法里,在每个测试方法(用例代码)执行前后都会自动调用的结构
PYTHON
1 2 3 4 5 6 7 8 def setup (self ): pass def teardown (self ): pass
类级别 在每个测试类中所有方法执行前后都会自动调用的结构(整个类中前后各一次)写在类里面
类级别的Fixture方法是一个类方法
PYTHON
1 2 3 4 5 6 7 8 @classmethod def setupClass (cls ): pass @classmethod def teardownClass (cls ): pass
模块级别 在每个代码文件执行前后执行的代码结构,需要写在类的外面,直接定义函数即可
PYTHON
1 2 3 4 5 6 def setupModule (): pass def teardownModule (): pass
方法级别和类级别的前后方法不需要同时出现,根据用例代码的需要自行的选择使用
登录案例
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 import unittestfrom day1.login_1 import loginclass LoginTest (unittest.TestCase): def setUp (self ): """每个测试方法执行之前都会先调用的方法""" print ('输入网址...' ) def tearDown (self ): """每个测试方法执行之后都会先调用的方法""" print ('关闭网站...' ) def test_username_password_ok (self ): print ('输入正确用户名和密码点击登录1' ) if login('admin' , '123456' ) == '登录成功' : print ('pass' ) else : print ('fail' ) @classmethod def setUpClass (cls ): print ('1. 打开浏览器' ) @classmethod def tearDownClass (cls ): print ('5. 关闭浏览器' ) def test_username_error (self ): print ('输入错误用户名和密码点击登录2' ) if login('root' , '123456' ) == '登录失败' : print ('pass' ) else : print ('fail' ) def test_password_error (self ): if login('admin' , '123123' ) == '登录失败' : print ('pass' ) else : print ('fail' ) def test_username_password_error (self ): if login('aaa' , '123123' ) == '登录失败' : print ('pass' ) else : print ('fail' )
测试add
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 """ 学习TestCase模块的书写方法 """ import unittestimport toolsclass TestAdd (unittest.TestCase): def test_method1 (self ): if tools.add(1 , 2 )==3 : print ('测试通过' ) else : print ('测试不通过' ) def test_method2 (self ): if tools.add(10 ,20 )==30 : print ('测试通过' ) else : print ('测试不通过' ) def test_method3 (self ): if tools.add(2 , 3 )==5 : print ('测试通过' ) else : print ('测试不通过' )
login函数测试
PYTHON
1 2 3 4 5 def login (username,password ): if username =='admin' and password=='123456' : return '登录成功' else : return '登录失败'
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 import unittestfrom day1.login_1 import loginclass LoginTest (unittest.TestCase): def test_username_password_ok (self ): if login('admin' , '123456' ) == '登录成功' : print ('pass' ) else : print ('fail' ) def test_username_error (self ): if login('root' , '123456' ) == '登录失败' : print ('pass' ) else : print ('fail' ) def test_password_error (self ): if login('admin' , '123123' ) == '登录失败' : print ('pass' ) else : print ('fail' ) def test_username_password_error (self ): if login('aaa' , '123123' ) == '登录失败' : print ('pass' ) else : print ('fail' )
断言 让程序代替人工自动判断预期结果和实际结果是否相符
断言的结果:True->用例通过,False->代码抛出异常,用例不通过
python自带的断言,判断两个字符串是否相等assert "hello" == "hello"
assert "hello"=="hello1" "出错啦"
判断是否包含assert "h" in "hello"
判断是否为True、False assertTrue
assert1
assertFalse
assert0
在unittest中使用断言,都需要通过self.断言方法
来试验
assertEqual assertEqual(预期结果,实际结果)
,判断预期结果和实际结果是否相等
如果相等,用例通过;如果不相等,用例不通过,抛出异常
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import unittestfrom day1.login_1 import loginclass LoginTest (unittest.TestCase): def test_username_password_ok (self ): self.assertEqual('登录成功' ,login('admin' , '123456' )) def test_username_error (self ): self.assertEqual('登录失败' ,login('root' , '123456' ) ) def test_password_error (self ): self.assertEqual('登录失败' , login('admin' , '123123' )) def test_username_password_error (self ): self.assertEqual('登录失败' , login('aaa' , '123123' ))
失败:
assertIn assertIn(预期结果,实际结果)
判断预期结果是否包含于实际结果
如果包含,用例通过;如果不不包含,用例不通过,抛出异常
assertTrue assertTrue(ex)
判断ex是否为True
参数化 解决相同业务逻辑,不同业务数据
在测试方法中,使用变量代替具体的测试数据,使用传参的方法将测试数据传递给方法的变量,可以减少相似代码的书写。测试数据一般放在json文件中,使用代码读取json文件,提取要的数据[(),(),()],[[],[]]
unittest框架本身不支持参数化,需要安装插件完成
PYTHON
1 2 3 4 1. 导包 unittest/parameterized2. 定义测试类3. 书写测试方法(用到的测试数据使用变量来代替)4. 组织测试数据并传参
login_1代码:
PYTHON
1 2 3 4 5 def login (username,password ): if username =='admin' and password=='123456' : return '登录成功' else : return '登录失败'
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import unittestfrom parameterized import parameterizedfrom day1.login_1 import logindata = [ ('admin' , '123456' , '登录成功' ), ('root' , '123456' , '登录失败' ), ('admin' , '123123' , '登录失败' ), ('root' , '123123' , '登录失败' ) ] class TestLogin (unittest.TestCase): @parameterized.expand(data ) def test_login (self, username, password, expect ): self.assertEqual(expect, login(username, password))
通过json导入
JSON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [ { "desc" : "正确的用户名密码" , "username" : "admin" , "password" : "123456" , "expect" : "登录成功" } , { "desc" : "错误的用户名" , "username" : "root" , "password" : "123456" , "expect" : "登录失败" } , { "desc" : "错误的密码" , "username" : "admin" , "password" : "123123" , "expect" : "登录失败" } , { "desc" : "错误的用户名和密码" , "username" : "aaa" , "password" : "123123" , "expect" : "登录失败" } ]
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import unittestfrom parameterized import parameterizedimport jsonfrom day1.login_1 import logindef build_data (): with open ('test.json' , encoding='utf-8' ) as f: res = json.load(f) data = [] for i in res: testtuple = (i.get('username' ), i.get('password' ), i.get('expect' )) data.append(testtuple) return data class TestLogin (unittest.TestCase, ): @parameterized.expand(build_data( ) ) def test_login (self, username, password, expect ): self.assertEqual(expect, login(username, password))
跳过 对于一些未完成的或者不满足测试条件的测试函数和测试类可以跳过执行,使用装饰器完成。代码书写在TestCase中
PYTHON
1 2 3 4 5 @unittest.skip('跳过原因' ) @unittest.skipIf(condition, reason )
PYTHON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import unittestversion = 30 class TestDemo (unittest.TestCase): @unittest.skip('没有什么原因就是不想执行' ) def test_1 (self ): print ('method 1' ) @unittest.skipIf(version >= 30 , '版本号新,不用测试' ) def test_2 (self ): print ('method 2' ) def test_3 (self ): print ('method 3' )
测试报告 自带的测试报告:只有单独运行TestCase的代码才能生成测试报告,组装打包的测试用例不能生成
HTMLTestRunner是一个类库,生成第三方的的测试报告需要用到。
获取第三方的测试运行模块,将其放在代码的目录中
导包
使用套件对象,加载对象添加用例方法
实例化第三方的运行对象并运行套件
组织用例文件(TestCase),书写参数化,书写断言,书写Fixture,书写跳过,如果单个测试文件直接运行,得到测试报告,如果有多个测试文件需要使用套件对象组装、加载对象组装运行生成测试报告。接下来要运行对象,使用第三方运行类进行运行。运行对象.run(套件对象)
PYTHON
1 2 3 4 5 6 7 8 9 10 import unittestfrom HtmlTestRunner import HTMLTestRunnersuite = unittest.defaultTestLoader.discover('.' , 'parametertest.py' ) HTMLTestRunner().run(suite)
unittest自带报告:
html报告: