前言
对于之前做Java开发的同学,自学Python还是比较简单的。在这里只是整理了Python里一些基础知识。
第一次发文章,不足之处,请大家多多指教
文章目录
一、输入和输出
1. 计算机输入内容
输入的内容,接收后都是字符串,就算输入数字,也是字符串
str = input("请输入内容:")
2. 输出
- 多条print输出多行,print函数默认会自动输出一个回车换行,所以多个print就会输出多行
print("加油!")
- 多条print输出到一行,固定输出的最后为空字符串,就是用空字符串替换掉默认的回车换行
(其实也可以用print(变量1,变量2…),不过要是循环输出的情况,就不适用了)
str1 = '今天很好,'
str2 = '明天更好'
print(str1,end = "")
print(str2)
执行结果:
今天很好,明天更好
二、注释
1,单行注释:和Java一样,使用ctrl + / 快速注释一行代码
# print("加油!")
2,多行注释:用三个单引号(自感觉怪怪的,不习惯使用,不如#方便)
'''
str = input("请输入内容:")
print("加油!")
'''
三、数据类型
在Python里定义变量就没有在Java里那么麻烦了,不用先写类型。不过必须定义赋值,
变量名 = 值,例如:(通过值就知道是个字符串类型)
name = "星"
即使这样,有哪些数据类型,肯定还是需要掌握的
1.整数类型(int)
整数包括正整数、负整数和0,位数是任意的
num = 10
2.浮点数(float)
浮点数是由整数部分和小数部分组成,主要是处理包括小数的数
num = 3.1415926
3.布尔类型(bool)
布尔类型主要是用来表示真(True)或假(False)的值。在Python里,布尔类型可以转化为数值,也就是可以当作数可以计算的
- True(真) 表示 1
- False(假) 表示 0
num1 = 2
bool1 = True
print(num1 + bool1)
执行结果:
G:\python\python.exe G:/pythod_work/test.py
3
Process finished with exit code 0
4.字符串(String)
(1)定义
字符串就是连续字符序列,可以表示所有字符的集合,通常使用单引号和双引号,或者三个单引号和三个双引号括起来。
单引号和双引号实现的是一样的,字符串内容都在一行
而三个单引号和三个双引号,字符串内容可以分布在连续的多行上
# 特意换个行,看一下它们的不同
str1 = '单引号str1_1' \
'单引号str1_2' # 按回车自动缩进的
str2 = "双引号str2_1" \
"双引号str2_2" # 按回车自动缩进的
str3 = '''三引号str3_1
三引号str3_2''' # 按回车没有自动缩进
str4 = """三个双引号str4_1
三个双引号str4_2""" # 按回车没有自动缩进
执行结果:
G:\python\python.exe G:/pythod_work/test.py
单引号str1_1单引号str1_2
双引号str2_1双引号str2_2
三引号str3_1
三引号str3_2
三个双引号str4_1
三个双引号str4_2
Process finished with exit code 0
(2)使用
- 拼接字符串,使用”+“进行拼接:字符串 + 字符串
- 字符串重复,使用”*“拼接整数:字符串 * 整数
- 注意:不能使用算数运算符和其他数字进行计算操作
str1 = '字符串1'
str2 = '字符串2'
print(str1 + str2)
print(str1 * 3)
执行结果:
字符串1字符串2
字符串1字符串1字符串1
(3)遍历字符串
str1 = "python"
for n in str1:
print(n)
(4)字符串常用的方法
分类 | 方法 | 说明 |
---|---|---|
查找 | 字符串[索引] | 得到字符串指定位置的字符 |
字符串.find(子串) | 找到就返回子串的位置,找不到返回-1 | |
判断 | 字符串.isalpha() | 判断字符串是否由纯字母组成 |
字符串.isdigit() | 判断字符串是否由纯数字组成 | |
字符串.islower() | 判断字符串是否全部由小写字母构成 | |
字符串.isupper() | 判断字符串是否全部由大写字母构成 | |
替换 | 字符串.replace(old, new) | 查找子串,并用新的子串替代旧的子串 |
统计 | 字符串.count(子串) | 统计子串出现次数 |
大小写转换 | 字符串.upper() | 小写字母改成大写字母 |
字符串.lower() | 将大写字母转化为小写 | |
字符串.swapcase() | 将大小写字母反转 | |
去除空格 | 字符串.lstrip() | 去除左侧空格 |
字符串.rstrip() | 去除右侧空格 | |
字符串.strip() | 去除左右两侧空格 | |
拆分 | 字符串.split(子串) | 根据子串拆分字符串 |
(5)格式化字符串
a.定义
格式化字符串就是先定义一个模板,在模板中预留几个空位(占位符),在根据需要填上相应的内容。在python里,实现格式化字符串使用“%”操作符。
b.语法
print(“格式化字符串” % (变量1, 变量2, …))
c.常用的格式化字符
-
格式化字符串
%s :采用str()显示(不带引号显示)
%r :采用repr()显示(带引号显示)
例:
str_s = "str"
str_r = "repr"
print("str_s显示为:%s,str_r显示为:%r" % (str_s,str_r))
执行结果:
str_s显示为:str,str_r显示为:'repr'
- 格式化十进制整数
(1)使用:%d或者%i,这两个没有区别
age1 = 18
age2 = 20
print("实际年龄:%d,心理年龄:%i" % (age1,age2))
执行结果:
实际年龄:18,心理年龄:20
(2)固定整数的位数:
% 0(位数不足补0)位数 d
% (不写:位数不足补空格) 位数 d
age1 = 18
age2 = 20
print("实际年龄:%010d,心理年龄:%5i" % (age1,age2))
执行结果:
实际年龄:0000000018,心理年龄: 20
- 格式化浮点数
(1)使用:%f或者%F,这两个没有区别
num1 = 3.14
num2 = 2.56
print("第一个f:%f,第二个F:%F" % (num1,num2))
执行结果:
第一个f:3.140000,第二个F:2.560000
(2)固定小数点后几位:
% . 保留小数点的位数 d
num1 = 3.1415926
num2 = 2.56
print("第一个f:%.4f,第二个F:%.1F" % (num1,num2))
执行结果:
第一个f:3.1416,第二个F:2.6
- 输出字符%
如果存在多个格式化字符时,要输出%,需要使用%%
name = "星"
age = 18
print("名:%s,年龄:%d,输出%%" % (name,age))
执行结果:
名:星,年龄:18,输出%
(6)切片
- 只要可以使用[索引]访问成员的数据类型,都可以使用切片
- [开始索引:结束索引:步长]
- 包含开始索引
- 不包含结束索引
- 省略开始索引,默认从0开始
- 省略结束索引,默认到最后
- 省略步长,默认步长为1
str1 = "qwerty"
str2 = str1[2:4:1]
print(str2)
str3 = str1[:4:1]
print(str3)
str4 = str1[2::1]
print(str4)
str5 = str1[2:4:]
print(str5)
执行结果:
er
qwer
erty
er
5.不同的数据类型之间的转化
(1)强制转化为字符串
- str(要转化的变量或者值)
num1 = 123
str1 = str(num1)
(2)强制转化为整数
- int(要转化的变量或者值)
str1 = "123"
num1 = int(str1)
注意:要转化的字符串里面必须是数字
(3)强制转化为浮点数
float(要转化的变量或者值)
str1 = "3.14159"
num1 = float(str1)
四、运算符
1.算数运算符
- 加(+)、减(-)、乘(*)、除(/)
- 取余数(%):返回除法的余数
- 取整除(//) :返回商的整数部分
- 幂(**):x **y就是x的y次方
优先级:幂(**)> 乘(*)、除(/)、取余数(%)、取整除(//)> 加(+)、减(-)
2.比较运算符
- 大于(>)、大于等于(>=)、等于(==)、小于(<)、小于等于(<=)、不等于(!=)
3.逻辑运算符
- 逻辑与(and):条件同时满足
- 逻辑或(or):条件满足其中一个
- 逻辑非(not):条件不满足
4.赋值运算符
- 简单赋值(=):x = y 等同于 y的值给x
- 加赋值(+=):x += y 等同于 x = x + y
- 减赋值(-=):x -= y 等同于 x = x - y
- 乘赋值(*=):x *= y 等同于 x = x * y
- 除赋值(/=):x /= y 等同于 x = x / y
- 取余数赋值(%=):x %= y 等同于 x = x % y
- 取整数赋值(//=):x //= y 等同于 x = x // y
- 幂赋值(**):x **= y 等同于 x = x ** y
五、转义字符
1,常见的转义字符
- 回车键:\n
- tab键 :\t
- 双引号“ :"
- 单引号‘ :’
- \ 键 :\
2,取消转义(写地址的字符串时,常用)
在字符串前面加r
print(r"C:\Users\Administrator\Desktop\小垃圾")
六、流程控制语句
1.选择语句
num1 = int(input("请输入一个数字:"))
if num1 >= 0 and num1 <= 10: # 条件表达式1
print("输入的为0到10之间的数字") # 条件表达式1成立执行的语句
elif num1 <= 20: # 条件表达式2
print("输入的为10到20之间的数字") # 条件表达式2成立执行的语句
else:
print("输入的为大于20的数字") # 以上条件都不成立执行的语句
2.循环语句
- while循环
一般应用于指定次数的循环
num1 = 0
while num1 < 10: # 条件表达式,如果条件不成立,那么循环终止
print(num1,end = "") # 条件成立,要循环执行的代码
num1 += 1
执行结果:
0123456789
- for循环
一般应用于遍历
str1 = "爱丫爱丫"
for n in str1: # for 迭代变量 in 对象
print(n) # 循环体
执行结果:
爱
丫
爱
丫
- break、continue和pass语句
(1)break语句
可以终止当前的循环
num1 = 0
while num1 < 10: # 条件表达式1
print(num1,end = '') # 条件表达式1成立,要循环执行的代码
if num1 > 5: # 条件表达式2
break # 条件表达式2成立,要终止当前的循环
num1 += 1
执行结果:
0123456
(2)continue语句
continue和break不同,它只能终止本次循环,跳过当前循环的剩余语句,提前进入下一次循环里
num1 = 0
while num1 < 10: # 条件表达式1
num1 += 1 # 条件表达式1成立,要循环执行的代码
if num1 == 5: # 条件表达式2
continue # 终止本次循环,跳过当前循环的剩余语句
print(num1,end = "") # 条件表达式1成立,要循环执行的代码
执行结果:(没有5,因为等于5时跳过了)
1234678910
(3)pass语句
pass语句表示空语句,不做任何处理,起到占位的作用
num1 = 0
while num1 < 10: # 条件表达式1
pass # 占位符
num1 += 1 # 条件表达式1成立,要循环执行的代码
- 人造死循环
# 如果while后面的条件为True,这个while就是一个人为的死循环
# 循环内部一定要有if结合break来让循环退出的机制
while True:
str1 = input("请输入一个字符串")
if str1 == "exit":
break
print(str1)
七、列表与元组
1.列表(list)
- 定义
list1 = ["2","3","4"] # 列表用[]定义
- 列表的常用方法
查看列表所有的方法:
print(dir(list))
执行结果:
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
对于这么多方法,整理了一些常用的供参考
分类 | 方法 | 说明 |
---|---|---|
增加 | insert(索引,值) | 在指定位置插入数据 |
append(值) | 在列表的末尾追加数据 | |
extend(列表) | 在列表的末尾追加另一个列表的值 | |
删除 | del(列表[索引]) | 删除指定索引的数据 |
remove(值) | 删除第一次出现的指定的数据 | |
pop() | 删除列表中最后一个成员 | |
pop(索引) | 删除指定索引的值,功能与del类似 | |
clear() | 清空列表 | |
修改 | 列表变量名[索引] = 值 | 修改指定索引的数据 |
查找 | 列表变量名[索引] | 查找指定索引的值 |
统计 | count(值) | 如果有多个一样的值,返回值的数量,如果一个没有,返回0 |
index(指定的值, 起始位置) | 返回指定值在列表中的索引编号,如果不写起始位置,默认为0 | |
排序 | sort() | 对列表成员从小到大排序 |
sort(reverse=True) | 对列表成员从大到小排序 | |
逆置 | reverse() | 把列表所有成员顺序颠倒 |
2.列表推导式
快速的生成数量庞大的列表
- 语法
列表变量名 = [x for x in range(开始值,结束值,步长)]
列表变量名 = [x for x in range(开始值,结束值,步长) if 条件]
- 例:
list1 = [x for x in range(0, 10) if x % 2 == 0]
print(list1)
执行结果:
[0, 2, 4, 6, 8]
3.元组(tuple)
- 定义
tuple1 = ("2","4","6") # 元组用()定义
相当于一个只读的列表
- 元组的常用方法
列表的常用方法除了修改值,其他的元组都适用
4.元组和列表的转化
- 元组转列表
- list(元组)
- 列表转元组
- tuple(列表)
八、集合与字典
1.集合(set)
- 定义
set1 = {'a', 'b', 'c'} # 集合用{}定义
- 常用方法
分类 | 方法 | 说明 |
---|---|---|
增加 | 集合变量.add(值) | 增加值 |
删除 | 集合变量.pop() | 删除最后一个值 |
remove(值) | 删除指定的值 | |
集合变量.clear() | 清空集合 |
- 集合和列表的区别
集合中所有成员是无序的,列表中所有成员是有序的
集合中成员的值不能重复,列表中成员的值可以重复
2.字典(dictionary)
- 定义
dict1= {'name':"嗷呜", 'add':'客厅'} # 字典用用{key:value}定义
注意:一个字典中key不能重复,键和值用冒号分隔
- 常用方法
分类 | 方法 | 说明 |
---|---|---|
增加/修改 | 字典[键] = 值 | 如果键存在,就是修改值,如果键不存在,就是新增键值对 |
删除 | 字典名.pop(键) | 删除键值对 |
字典名.clear() | 清空字典 | |
查值 | 变量名 = 字典名[键] | 得到键对应的值 |
- for循环遍历字典
dict1= {'name':"嗷呜", 'add':'客厅'}
for n in dict1:
print("key: %s,value:%s" % (n,dict1[n]))
执行结果:
key: name,value:嗷呜
key: add,value:客厅
- items遍历字典
字典.items()返回一个包含键和值的元组
dict1= {'name':"嗷呜", 'add':'客厅'}
for n in dict1.items():
print(n)
执行结果:
('name', '嗷呜')
('add', '客厅')
3.集合和字典的区别
- 集合里面只有值
- 字典里面是键值对
九、公共方法
1.len
返回成员的个数
- len(字符串) – 返回字符串中字符的数量
- len(列表) – 返回的是列表中成员的数量
2.max
返回列表中的最大值
- max(列表) – 返回列表中最大的值
- max(字符串) – 返回字符串中ASCII最大的那个字符
3.min
返回列表中的最小值
- min(列表) – 返回列表中最小的值
- min(字符串) – 返回字符串中ASCII最小的那个字符
4.in
判断指定的值是否在列表中存在
- 指定的值 in 列表
- 指定的子串 in 字符串
5.not in
判断指定的值是否不在列表中
- 指定的值 not in 列表
- 指定的子串 not in 字符串
十、函数
1.定义
a,b为形参
return后面为函数的返回值
def my_sum(a,b): # def 函数名(参数1, 参数2, .....):
return a + b # 函数内部封装的代码
2.调用
my_sum(23,34) # 函数名()
3.变量作用域
- 局部变量
- 定义位置:函数内部定义的变量就是局部变量
- 使用范围:局部变量只能在函数内部使用
- 命名:不同的函数局部变量名字可以相同
- 内存:局部变量从调用函数的时候开始在内存出现,函数调用完毕,局部变量从内存消失
- 全局变量
- 定义位置:函数外部定义的变量就是全局变量
- 使用范围:全局变量可以在所有函数内部使用
- 内存:全局变量从程序开始时在内存中出现,一直到程序运行完成,和程序一起从内存中消失
注意:局部变量能解决的问题,尽量少定义全局变量
- 局部变量与全局变量重名
如果在函数内部定义一个局部变量名字和全局变量重名,那在这个函数内部只能使用局部变量
num1 = 10 # 全局变量
def update_num():
num1 = 20 # 局部变量,和全局变量重名
update_num() # 调用函数
print(num1)
执行结果:
10
- global关键字:(局部变量与全局变量重名,想在函数内部修改全局变量的值,这就需要global关键字)
num1 = 10 # 全局变量
def update_num():
global num1 # 用global关键字修饰局部变量
num1 = 20 # 局部变量,和全局变量重名
update_num() # 调用函数
print(num1)
执行结果:
20
- 形参的缺省值
当调用函数的时候,如果没有提供相应的实参,那么形参可以采用缺省值
def my_sum(a, b = 10): # 形参b有缺省值,当b不给值时,就是10
print(a + b)
my_sum(5)
执行结果:
15
4.lambda匿名函数
就是迷你版函数
- 语法
# lambda 参数1, 参数2, ..... : 函数执行代码
num1 = lambda a,b:a + b
num2 = (lambda a, b : a if a > b else b)(3, 5)
print(num1(3,5))
print(num2)
执行结果:
8
5
十一、其他常用的函数
1.生成随机数
- 语法
start和end是两个整数,代表要生成的随机数的范围
import random
num1 = random.randint(start,end)
- 使用
import random
num1 = random.randint(0,5)
print(num1)
执行结果:(这个结果就是从0到5随机输出的)
5
2.range函数
用于生成指定范围的数字序列
- 语法
range(start, end, step)
start代表范围的开始值
end代表范围的结束值,但不包含end
step代表步长,可以为负数,正数就是升序范围,负数就是降序范围
for a in range(0, 5):
print(a,end='')
执行结果:
01234
十二、类与对象
1.定义类
class cat: # class 类名
def eat(self):
print("猫吃饭")
2.实例化对象
c = cat() # 对象名 = 类名(参数列表)
c.eat() # # 对象创建后通过对象名.方法名(参数),调用方法
执行结果:
猫吃饭
3.self参数的作用
- self可以在方法内部定义和使用属性,还可以在方法内部嵌套调用其他方法
- 在类的外部,是不能使用self的
class cat:
def set_name(self):
self.name = "嗷呜" # 定义了一个属性,名叫name,值是嗷呜
def eat(self): # 第一个参数必须是self
print("%s吃饭" % self.name) # 通过self使用name属性
def demo(self):
self.eat() # 在类的内部,方法嵌套调用
4.__init__方法
创建对象的时候,也就是实例化对象的时候,__init__方法被自动调用
class cat:
def __init__(self):
print("__init__被创建了")
def eat(self):
print("猫咪吃饭")
c = cat() # 实例化对象的时候,init方法自动调用
执行之后:
__init__被创建了
init方法的作用
- 定义类中的属性
- 通过init方法的参数为属性赋值
- init方法一旦有形参,对象实例化的时候就必须提供实参
- 为了避免实例化的时候必须提供实参,init的形参总是有缺省值的
5.__del__方法
当对象在内存中销毁的时候,会自动调用del方法
class cat:
def __init__(self):
print("__init__被自动创建")
def eat(self):
print("猫咪吃饭")
def __del__(self):
print("自动销毁")
c = cat() # 实例化对象的时候,init方法自动调用
# 程序执行完毕,自动调用对象的del方法
执行结果:
__init__被自动创建
自动销毁
6.__str__方法
必须有return,返回一个字符串
- str方法的作用
- 将带有str方法的对象放到print函数里,会输出str方法里return返回的字符串
- 如果类没有str方法,将类实例化的对象放到print函数里,输出的是对象的内存地址
class cat:
pass
c = cat()
print(c)
class dog:
def __init__(self, name = "狗子"):
self.name = name
def __str__(self):
return self.name
d = dog()
print(d)
执行结果:
<__main__.cat object at 0x000001A71E9589E8>
狗子
7.类属性
- 定义:定义在类里面,方法外面
class dog:
name = "狗子" # 在这个位置定义的变量,就是类属性
def eat(self):
pass
print(dog.name) # 显示类属性的值
dog.name = "二哈" # 修改类属性的值
print(dog.name)
执行结果:
狗子
二哈
8.类方法
- 定义:用@classmethod来修饰的方法,就是类方法
class dog:
name = "狗子" # 在这个位置定义的变量,就是类属性
@classmethod
def set_name(cls, name):
cls.name = name # 通过类方法的形参修改类属性name值
print(dog.name) # 显示类属性的值
dog.set_name("汪汪") # 通过类名.类方法名调用
print(dog.name)
执行结果:
狗子
汪汪
注意:
-
类方法的一个参数是cls,不是self
-
类方法内部不能使用普通属性,也不能调用普通方法
- 因为类方法不需要对象的,但普通方法和普通属性一定需要通过对象调用
-
在普通方法中可以通过类名.类属性或者类名.类方法使用类属性和类方法
class dog:
name = "狗子"
@classmethod
def get_name(cls):
return cls.name
def demo(self):
dog.name = "二哈" # 通过类名.类属性调用类属性
print(dog.get_name()) # 通过类名.类方法调用类方法
d = dog()
d.demo()
执行结果:
二哈
9.静态方法
- 定义:用@staticmethod修饰的方法就是静态方法
- 静态方法不能访问类中的其他成员,静态方法就是一个独立与类存在的函数
class cat:
@staticmethod
def eat():
print("eat")
cat.eat() # 不需要实例化为对象,通过类名.静态方法名调用
十三、面向对象的特性
这对学过Java的同学应该张口就来,封装、继承和多态
接下来展开说
1.封装
- 就是把类的属性和方法封装到类的内部,只能在类的内部使用,不能在类的外部使用
- 在属性和方法名前面加两个下划线,这样属性和方法就成为了类的私有属性和方法
class cat:
def __eat(self): # __eat方法为私有方法
print("没有什么是好吃的不能解决的")
c = cat()
c.__eat() # 调用私有方法就报错了
2.继承(派生)
继承发生在父子类之间,子类(派生类)继承父类(基类),就会拥有父类的所有属性和方法
class father:
def eat(self):
print("吃")
class son(father): # 子类(父类),子类继承了父类
pass
s = son()
s.eat()
执行结果:
吃
3.多态
不同的子类,调用相同的父类方法,产生不同的结果
这也就是重写里的覆盖父类的方法
class animal:
def food(self):
pass
def eat(self):
self.food()
class dog(animal):
def food(self):
print("吃肉")
class cattle(animal):
def food(self):
print("吃草")
d = dog()
d.eat()
c = cattle()
c.eat()
执行结果:
吃肉
吃草
4.重写
方法重写有两种方式
- 覆盖父类方法(上面多态里的例子就是覆盖)
类中出现和父类相同的方法,那么在子类中相同方法会把父类的方法覆盖 - 扩展父类方法
父类的方法不能完全满足子类需求时,子类可以在父类方法基础上扩展功能
class animal:
def eat(self):
print("吃")
class dog(animal):
def eat(self):
super().eat() # 在子类方法中调用父类的eat方法
print("吃得更多")
d = dog()
d.eat() # 扩展了父类的eat
执行结果:
吃
吃得更多
十四、文件操作
1.操作步骤
- 读文件
file1 = open(r'G:\test_file\file1.txt','r',encoding='utf-8') # 一,打开文件-open
txt = file1.read() # 二,读文件
file1.close() # 三,关闭文件
- 写文件
这种写入的方式,会把之前文件里的内容覆盖掉
file2 = open(r'G:\test_file\file2.txt','w',encoding='utf-8') # 一,打开文件-open
file2.write('哈哈哈') # 二,写入文件
file2.close() # 三,关闭文件
- 追加写文件
file3= open(r'G:\test_file\file.txt','a',encoding='utf-8') # 一,打开文件-open
file3.write('追加') # 二,追加写入文件
file3.close() # 三,关闭文件
- 以上的区别就是打开文件open的参数不一样
- “r”:代表只读方式打开文件
- “w”:代表用写的方式打开文件,文件不存在就创建一个新文件
- “a”:代表当文件存在的时候,在文件后面追加内容,当文件不存在的时候创建新文件
- “rb”:代表用二进制方法打开,只读
- “wb”:代表用二进制方法打开,只写
- “ab”:代表用二进制方法打开,追加
2.读取文件的方式
- read():一次把文件所有内容都读取出来
- readline():按行读取文件内容
每调用一次readline,内部的文件指针就会指向下一行,这样下次再次调用readline会自动读取下一行,读取到文件最后,返回""
file7 = open(r'G:\test_file\file7.txt','r',encoding='utf-8')
txt7 = file7.readline() # 按行读取
while True:
txt7 = file7.readline()
if txt7 == '':
break
print(txt7)
file7.close()
- readlines():一下读取文件所有行,返回一个列表,列表中的一个成员就是文件中的一行,,文件有多少行,列表就有多少成员
file8 = open(r'G:\test_file\file8.txt','r',encoding='utf-8')
list8 = file8.readlines()
print(list8)
file8.close()
3.with open语法
是file = open的一种简化语法, 不需要明确的调用close关闭文件
with open(r'G:\test_file\file6.txt','r',encoding = 'utf8') as file:
txt = file.read()
print(txt)
4.json文件
(1)文件内容
- 大括号内部是键值对,多个键值对用逗号分隔
- 对象用大括号
- 列表用中括号
- 字符串用双引号
- 数字不需要引号
{
"name": "xing",
"age": 18
}
(2)读取json文件
import json # 一,导入json模块
file = open('data1.json','r',encoding='utf8') # 二,打开json文件
data = json.load(file) # 三,调用json模块的load方法
file.close() # 四,关闭文件
(3)写入json文件
import json # 一,导入json模块
file1 = open('data1.json','w',encoding = 'utf8') # 二,用只写方式打开json文件
dict1 = {'jia':'you','wo':'ni'}
json.dump(dict1,file1,ensure_ascii=False) # 三,调用json模块的dump方法
file1.close() # 四,关闭文件
十五、UnitTest自动化测试框架
1.TestCase
测试用例
import unittest # 一,导入unittest模块
def my_sum(a, b):
return a + b
class test01(unittest.TestCase): # 二,实现一个类,这个类必须继承自unittest.TestCase类
def test_001(self): # 三,类中每个方法代表一个测试用例,方法名以test开头
print(my_sum(5, 6))
def test_002(self):
print(my_sum(0, 3))
2.TestSuite
测试套件,把多个TestCase集成到一个测试TestSuite
import unittest # 一,import导入unittest
import testcase_01 # 二,import导入其他的包含测试用例的py文件
suite = unittest.TestSuite() # 三,实例化unittest.TestSuite类的对象
# 四,调用对象的addTest方法,只是把测试用例添加到了测试套件中,并不是执行测试用例
suite.addTest(testcase_01.my_test("test_001"))
suite.addTest(testcase_01.my_test("test_002"))
3.TextTestRunner
执行在suite中的测试用例
import unittest # 一,import导入unittest
import testcase_01 # 二,import导入其他的包含测试用例的py文件
suite = unittest.TestSuite() # 三,实例化unittest.TestSuite类的对象
# 四,调用对象的addTest方法,只是把测试用例添加到了测试套件中,并不是执行测试用例
suite.addTest(testcase_01.my_test("test_001"))
suite.addTest(testcase_01.my_test("test_002"))
runner = unittest.TextTestRunner() # 五,实例化TextTestRunner的对象
runner.run(suite) # 六,调用对象的run方法
4.TestLoader
在指定目录查找指定py文件中的所有测试用例,自动加载到TestSuite中。
import unittest
# 用TestLoader对象的discover方法来自动查找py文件,自动加载py文件中的方法
# 第一个参数是从哪里找py文件,"."从当前目录开始查找py文件
# 第二个参数是指定py文件的文件名,可以用通配符
suite = unittest.TestLoader().discover(".", "test*.py")
runner = unittest.TextTestRunner()
runner.run(suite)
5.Fixture
在测试用例执行前后自动调用指定的函数
- 方法级
每个方法执行前后都自动调用函数
import unittest
def my_sum(a, b):
return a + b
# 在TestCase,也就是测试用例所在的class中定义方法
class my_test(unittest.TestCase):
def setUp(self): # 当测试用例执行前,自动被调用
print("setup被自动调用了")
def tearDown(self): # 当测试用例执行后,自动被调用
print("teardown被自动调用了")
def test_001(self):
print(my_sum(5, 6))
- 类级
一个类执行前后都自动调用函数
import unittest
def my_sum(a, b):
return a + b
class my_test(unittest.TestCase):
@classmethod # 类开始时自动调用的方法
def setUpClass(cls):
print("setupclass自动调用了")
@classmethod # 类结束的时候自动调用的方法
def tearDownClass(cls):
print("teardownclass自动调用了")
def test_001(self):
print(my_sum(5, 6))
- 模块级
不管一个模块(一个模块就是一个py文件)中有多少类,模块执行前后自动调用的函数
import unittest
# 不管py文件中有多少个类,以及类中有多少方法,只自动执行一次
def setUpModule():
print("setUpModule自动调用了")
def tearDownModule():
print("tearDownModule自动调用了")
def my_sum(a, b):
return a + b
class my_test1(unittest.TestCase):
def test_001(self):
print(my_sum(5, 6))
class my_test2(unittest.TestCase):
def test_001(self):
print(my_sum(5, 6))
6.断言
程序来判断测试用例执行结果是否符合预期
assertEqual(参数1, 参数2)
assertIn(参数1, 参数2)
…
import unittest
def my_sum(a, b):
return a - b
class my_test(unittest.TestCase):
def test_001(self):
num1 = my_sum(5, 6)
self.assertEqual(num1, 11) # assertEqual(参数1, 参数2),如果参数1,参数2的值相等,断言成功,否则断言失败
7.参数化
多个测试用例代码相同,只是测试数据不同,预期结果不同,通过参数化技术合并为一个测试用例
import unittest
from parameterized import parameterized # 第一步:导入from parameterized import parameterized
def my_sum(a, b):
return a + b
class my_test1(unittest.TestCase):
# 第二步:在方法上面用@parameterized.expand()修饰方法
@parameterized.expand([(1, 2, 3), (5, 6, 110), (-1, 3, 2)]) # expand()里面是一个列表,列表里每个元组中的成员就代表调用方法使用的实参
def test_001(self, a, b, c):
num1 = my_sum(a, b)
self.assertEqual(num1, c)
8.跳过
通过@unittest.skip跳过指定的方法或者函数
import unittest
def my_sum(a, b):
return a + b
class my_test(unittest.TestCase):
@unittest.skip
def test_001(self):
print("test001")
9.生成测试报告
- 通过TextTestRunner生成
import unittest
suite = unittest.TestLoader().discover("./","test*.py")
# 用TextTestRunner生成测试报告
file = open(r'test01.txt','w',encoding = 'utf8') # 第一步:用open,w方式打开测试报告文件
runner = unittest.TextTestRunner(stream = file,verbosity = 2) # 第二步:实例化TextTestRunner对象
runner.run(suite) # 第三步调用对象的run方法执行测试套件
file.close() # 关闭open打开的文件
- 调用HTMLTestRunner生成
import unittest
from HTMLTestRunner import HTMLTestRunner # 第一步,在代码中导入模块from HTMLTestRunner import HTMLTestRunner
suite = unittest.TestLoader().discover("./","test*.py")
# 用HTMLTestRunner生成测试报告
file1 = open(r"test02.html",'wb') # 第二步,打开文件
runner1 = HTMLTestRunner(stream = file1,title = "测试报告") # 第三步,调用HTMLTestRunner(
runner1.run(suite) # 第四步,调用runner对象的run方法执行测试套件
file1.close() # 第五步,关闭open打开的文件
十六、异常
1.捕获异常
try:
a = int(input("请输入一个整数")) # 可能出异常的代码
b = int(input("请输入一个整数"))
print(a / b)
except ValueError: # except 异常类型1:
print("请输入一个可以转化整数") # 出现异常类型1执行的代码
except ZeroDivisionError: # except 异常类型2:
print("除数不能为0") # 出现异常类型2执行的代码
except:
print("未知错误") # 出现未知异常执行的代码
else:
print("没有异常发生") # 没有异常发生执行的代码
finally:
print("不论是否有异常都要执行的代码") # 不管是否有异常都要执行的代码
2.主动抛出异常
raise Exception("主动抛出的异常") # 这个异常是自己人为抛出
十七、模块
一个py文件就是一个模块
1.import 导入模块
# 在module2.py里面使用module1.py中定义的函数
import module1 # import 模块名
module1.my_sum(3, 4) # 模块名.函数
2.导入模块同时起别名
# 在module2.py里面使用module1.py中定义的函数
import module1 as m # import 模块名 as 别名
m.my_sum(3, 4) # 别名.函数名
3.from import导入指定内容
# 只想导入module1中的my_max函数
from module1 import my_max # from 模块名 import 函数名
my_max(4, 5) # 直接写函数名调用
也可以全部函数一起导入
# 只想导入module1中的my_max函数
from module1 import * # from 模块名 import *
my_max(4, 5) # 直接写函数名调用
4.__name__属性
每一个模块都有一个属性__name__
- 如果正在执行的模块里,输出name属性的值为__main__
- 如果这个py文件是被其他py文件import导入调用的,那name属性的值就是这个py文件的模块名
十八、包
- 定义:包就是一个特殊的目录,目录下有__init__.py文件
- 用处:使用包的目的是一次性可以把一个目录下所有的模块通过一条import语句导入
新建一个目录,my_pack,在这个目录下新建三个文件
my_pack1/m1.py
def m1_func():
print("我是m1的func函数")
def m1_test():
print("我是m1的test函数")
my_pack1/m2.py
def m2_func():
print("我是m2的func函数")
my_pack1/init.py
from . import m1
from . import m2
最后在其他文件里导入,通过包名全部导入
import my_pack1
# my_pack1.m1.m1_func()
# my_pack1.m1.m1_test()
# my_pack1.m2.m2_func()
# from my_pack1.m1 import m1_test
# from my_pack1.m1 import m1_func
# from my_pack1.m2 import m2_func
总结
整理了一天(呼~),以上就是我这周学习的Python的基础。充实的一周,不能白看,所以汇整了一下这周的学习内容。希望给其他想学Python的同学或者想学自动化测试的同学一点点的参考。(在此鞠躬)