python基础学习

这篇博客详细介绍了Python的基础知识,包括输入输出、数据类型、运算符、字符串格式化、流程控制、列表与元组、集合与字典、函数、面向对象编程、文件操作、自动化测试框架UnitTets等。适合初学者学习和巩固Python基础。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

对于之前做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的同学或者想学自动化测试的同学一点点的参考。(在此鞠躬)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值