本文目录
一、常用的转义字符
转义字符的分类 | 要表示的字符 | 转义字符 | 备注 |
---|---|---|---|
无法表示的字符 | 换行 | \n | newline光标移动到下一行的开头 |
回车 | \r | return 光标移动到本行的开头 | |
水平制表符 | \t | tab键,光标移动到下一组4个空格的开始处 | |
退格 | \b | 键盘上的Backspace键,回退一个字符 | |
在字符串中有特殊用途的字符 | 反斜杠 | \\ | |
单引号 | \* | ||
双引号 | \" |
二、Python的标识符和保留字
2.1 保留字
定义: 保留字(reserved word),指在高级语言中已经定义过的字,使用者不能再将这些字作为变量名或过程名使用。
查看python中的所有保留字
import keyword
print(keyword.kwlist)
结果
['False', 'None', 'True', '__peg_parser__', 'and', 'as', 'assert', 'async', 'await', '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']
2.2 标识符
定义: 标识符(identifier)是指用来标识某个实体的一个符号,在不同的应用环境下有不同的含义。在计算机编程语言中,标识符是用户编程时使用的名字,用于给变量、常量、函数、语句块等命名,以建立起名称与使用之间的关系。标识符通常由字母和数字以及其它字符构成。
规则:
-
由字母、数字、下划线构成
-
不能以数字开头
-
不能是保留字
-
严格区分大小写
三、Python的数据类型
类型 | 英文 | 表示方式 | 描述 |
---|---|---|---|
整数 | Integer | int | 可表示正数、负数和零 |
浮点型 | float | 存储不精确,使用其进行计算时,可能出现小数位数不确定的情况 | |
布尔型 | Boolean | bool | 用来表示真假的值,可以转化为整数进行计算 |
字符串 | str | 字符串又被称为不可变的字符序列,可以使用单引号: ’ ’ ,双引号: " “,三引号: ‘’’ ‘’'或”"" “”"来定义,单引号和双引号定义的字符串必须在一行,三引号定义的字符串可以分布在连续的多行 |
浮点数计算时出现小数位数不确定的解决方案:
导入模块decimal
from decimal import Decimal
n1 = 1.1
n2 = 2.2
print(n1+n2) #小数位数不确定
print(Decimal('1.1')+Decimal('2.2')) #解决方案
布尔型举例
f1 = True # 不能使用true
f2 = False # 不能使用false
print(f1,type(f1))
print(f2,type(f2))
print(f1+1) # 结果为2
print(f2+1) # 结果为1
字符串举例
str1 = '测试'
str2 = "测试"
str3 = """测
试"""
#下列写法 报错
# str4 = "测
# 试"
四、数据类型转化
函数名 | 作用 | 注意事项 | 举例 |
---|---|---|---|
str() | 将其他数据类型转化成字符串 | 也可用引号转化 | str(123) ‘123’ |
int() | 将其他数据类型转化成整数 | 1.文字类和小数类字符串,无法转化为整数 2.浮点数转化为整数:抹零取整 | int(‘123’) int(9.8) |
float() | 将其他数据类型转成浮点数 | 1.文字类型无法转成浮点数 2.整数转成浮点数,末尾为.0 | float(‘9.9’) float(9) |
进行数据类型转换的目的是为了将不同数据类型的数据拼接到一起进行输出
name='张三'
age=12
#下面注释语句输出报错,TypeError: can only concatenate str (not "int") to str
# print(name+age)
#解决方案,数据类型转化,将int类型转成str类型
print(name+str(age))
五、代码注释
单行注释:以"#"开头,直到换行结束
多行注释:没有单独的多行注释标记,将一对三引号之间的代码称为多行注释
中文编码声明注释:在文件开头加上中文声明注释,用以指定源码文件的编码格式,如:#coding:gdk
# 单行注释
'''
多行注释
'''
"""
多行注释
"""
六、运算符
6.1 算数运算符
print(1+1) #加法运算 结果为2
print(2-1) #减法运算 结果为1
print(1*3) #乘法运算 结果为3
print(3/2) #除法运算 结果为1.5
print(3//2) #整除运算 结果为1
print(3%2) #取余运算 结果为1
print(2**3) #幂运算 结果为8
print(5%-2) #公式:余数=被除数-除数*商 5-(-2)*(-3)=5-6=-1 商为-2.5,取整为-3
print(-5%2) # -5-2*(-3)=-5+6=1
print(-9//4) # 一正一负的整数公式,向下取整 -9//4为 -3
print(9//-4) # -3
6.2 赋值运算符
变量的值交换:
a,b=10,20
print("交换之前的值:",a,b)
a,b=b,a
print("交换之后的值:",a,b)
6.3 比较运算符
6.4 布尔运算符
运算符 | 运算数 | 运算结果 | 备注 | |
and | True | True | True | 当两个运算数都为True时,运算结果才为True |
True | False | False | ||
False | True | |||
False | False | |||
or | True | True | True | 只要有一个运算数为True,运算数就为True |
True | False | |||
False | True | |||
False | False | False | ||
not | True | False | 如果运算数为True,运算结果为False | |
False | False | 如果运算数为False,运算结果为True |
对象的布尔值:
print(bool(False)) #False
print(bool(0)) #False
print(bool(0.0)) #False
print(bool(None)) #False
print(bool('')) #False
print(bool("")) #False
print(bool([])) #空列表
print(bool(list())) #空列表
print(bool(())) #空元组
print(bool(tuple())) #空元组
print(bool({})) #空字典
print(bool(dict())) #空字典
print(bool(set())) #空集合
# 其他对象布尔值皆为True
6.5 位运算符
6.6 运算符的优先级
七、python的相关程序结构
7.1 单分支结构
if 条件表达式:
条件执行体
7.2 双分支结构
if 条件表达式:
条件执行体1
else:
条件执行体2
7.3 多分支结构
if 条件表达式1:
条件执行体1
elif 条件表达式2:
条件执行体2
elif 条件表达式N:
条件执行体N
[else:]
条件执行体N+1
7.4 嵌套if
if 条件表达式1:
if 内层条件表达式:
内层条件执行体1
else:
内层条件执行体2
else:
条件执行体
7.5 条件表达式(if…else的简写)
"""
语法:
x if 判断条件 else y
运算规则:
如果判断条件的布尔值为True,条件表达式的返回值为x,否则条件表达式的返回值为y
例子:
"""
num_a=1
num_b=2
print(num_a if num_a<num_b else num_b)
7.6 循环结构
while循环
# 需求:求1到100之间的偶数和 sum = 0 i = 1 while i<=100: if(i%2==0): sum += i i+=1 print(sum)
for-in循环
in表达从(字符串、序列等)中依次取值,又称为遍历
for-in的语法结构
for 自定义的变量 in 可迭代对象:
循环体
例子:
#for-in循环 for item in "Python": #第一次取出来的值为P,将P赋值给item,将item输出 print(item) for i in range(5): #range()产生一个整数序列 print(i) for _ in range(5): #循环体中不需要用到自定义变量,可将自定义变量使用下划线代替 print("你好") #使用for-in计算1-100的偶数和 sum2 = 0 for i in range(0,101): if i%2==0: sum2 += i print(sum2)
结果:
P y t h o n 0 1 2 3 4 你好 你好 你好 你好 你好 2550
注:可以使用break、continue语句结束循环,break是结束循环结构,continue是跳过当前循环
嵌套循环
# 九九乘法表 for i in range(1,10): for j in range(1,i+1): print(i,"*",j,"=",i*j,end="\t") print()
八、相关函数和语句
8.1 print()函数
功能:向目的地输出内容
输出的内容:数字、字符串、表达式
目的地:IDLE、控制台、文件
例子:
- 换行输出
print('hello,world')
- 不换行输出
print('hello','world') print(1,end="") #可以使循环中不换行输出
- 输出到文件中
ps = open('D:/text.txt','a+') #a+表示没有文件则新建 print('hello,world',file=ps)
8.2 input()函数
功能:接收来自用户的输入
返回值类型:输入值的类型为str
值的存储:使用=对输入的值进行存储
例子:
- 简单使用
#输入函数input() present = input("你好啊") print(present)
结果
你好啊你好啊 你好啊
- 高级使用
a=input("请输入被加数:") b=input("请输入加数:") a=int(a) b=int(b) print("结果为"+str(a+b))
结果输出为
请输入被加数:1 请输入加数:2 结果为3
8.3 pass语句
作用:pass语句什么都不做,只是一个占位符,用在语法上需要语句的地方
适用场合:先搭建语法结构,还没想好代码怎么写的时候
跟哪些语句一起使用:
- if语句的条件执行体
- for-in 语句的循环体
- 定义函数时的函数体
例子:
a=1
if a!=1:
print("2")
else:
pass
8.4 内置函数range()
-
作用:用于生成一个整数序列
-
创建方式:
-
返回值:一个迭代器对象
-
优点:不管range对象表示的整数序列有多长,所有range对象所占用的内存空间都是相同的,因为只需要存储start,stop和step,只有当用到range对象时,才会去计算序列中的相关元素
-
in与not in 判断整数序列中是否存在(不存在)指定的整数
例子:
r = range(10)
print(r)
print(list(r)) # 用于查看range对象的整数序列 list表示列表的意思
print(10 in r)
print(9 in r)
print(10 not in r)
print(list(range(1,20)))
print(list(range(1,20,2)))
结果为:
range(0, 10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
False
True
True
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
8.5 else语句
# if条件表达式不成立时执行else
if ... :
...
else:
...
# 没有遇到break且循环结束时执行else
while ...:
...
else:
...
for ... :
...
else:
...
九、列表
9.1 创建列表的方式
# 创建列表的方式
#方式一:使用[]
lst2 = ['hello','world']
#方式二:使用内置函数list()
lst2 = list(['hello','world'])
9.2 列表的特点
9.3 列表的查询操作
获取列表中指定元素的索引 index():
- 如查列表中存在N个相同元素,只返回相同元素中的第一个元素的索引
- 如果查询的元素在列表中不存在,则会抛出ValueError
- 还可以在指定的start和stop之间进行查找
lst = ["a","b",11,20] print(lst.index("a")) print(lst.index("b",1,4))
获取列表中的单个元素:
- 正向索引从0到N-1,举例:lst[0]
- 逆向索引从-N到-1,举例:lst[-N]
- 指定索引不存,则抛出IndexError
lst = ["a","b",11,20,"kk"] # 正向索引 print(lst[1]) # 逆向索引 print(lst[-1])
获取列表中的多个元素(切片操作):
# 代码示例: lst = [10,20,30,40,50,60,70,80] print(lst[1:6]) # [20, 30, 40, 50, 60] print(lst[:5:2]) # [10, 30, 50] print(lst[1::3]) # [20, 50, 80] print("-----------------------step为负数---------------------") print(lst[:3:-1]) # [80, 70, 60, 50] print(lst[::-1]) # [80, 70, 60, 50, 40, 30, 20, 10] print(lst[-1]) # 80 print(lst[4::-1]) # [50, 40, 30, 20, 10]
判断指定元素在列表中是否存在:
元素 in 列表名
元素名 not in 列表名
列表元素的遍历:
for 迭代变量 in 列表名:
操作
9.4 列表元素的增加操作
方法 | 操作描述 |
---|---|
append() | 在列表的末尾添加一个元素 |
extend() | 在列表的末尾至少添加一个元素 |
insert() | 在列表的任意位置添加一个元素 |
切片 | 在列表任意位置添加至少一个元素,实际是将切掉的部分用新的数据进行代替 |
举例:
lst = [10,20,30,40]
print("未添加元素之前的列表:",lst)
lst.append(91)
print("append()添加元素之后的列表:",lst)
lst1 = [True,30,39]
lst2 = [80,88]
lst1.extend(lst2)
print("extend()添加元素之后的列表:",lst1)
lst1.insert(3,9999)
print("insert()添加元素之后的列表:",lst1)
lst3 = [1,2]
lst3[1:] = lst2
print("切片方法在列表任意位置添加多个元素:",lst3)
结果:
未添加元素之前的列表: [10, 20, 30, 40]
append()添加元素之后的列表: [10, 20, 30, 40, 91]
extend()添加元素之后的列表: [True, 30, 39, 80, 88]
insert()添加元素之后的列表: [True, 30, 39, 9999, 80, 88]
切片方法在列表任意位置添加多个元素: [1, 80, 88]
9.5 列表元素的删除操作
方法/其他 | 操作描述 |
---|---|
remove() | 一次删除一个元素,重复元素只删除第一个,元素不存在抛出ValueError |
pop() | 删除一个指定索引位置上的元素,指定索引不存在则抛出IndexError,不指定索引则删除表中最后一个元素 |
切片 | 一次至少删除一个元素 |
clear() | 清空列表 |
del | 删除列表 |
举例:
lst = [10,20,30,40,50,60,70]
print("原列表",lst)
'''使用remove()进行删除'''
lst.remove(20)
print(lst)
'''使用pop()进行删除'''
lst.pop() # 不指定索引,删除列表最后一个元素
print(lst)
lst.pop(1)
print(lst)
'''切片删除,实质是将切片的元素使用空列表代替'''
lst[1:3] = []
print(lst)
'''clear() 清空列表'''
lst.clear()
print(lst)
'''del 删除列表'''
del lst
结果:
原列表 [10, 20, 30, 40, 50, 60, 70]
[10, 30, 40, 50, 60, 70]
[10, 30, 40, 50, 60]
[10, 40, 50, 60]
[10, 60]
[]
9.6 列表元素的修改
lst = [10,20,30,40,50,60]
print("原列表:",lst)
lst[3] = 999
print(lst)
lst[1:4] = [33,55,66]
print(lst)
结果:
原列表: [10, 20, 30, 40, 50, 60]
[10, 20, 30, 999, 50, 60]
[10, 33, 55, 66, 50, 60]
9.7 列表元素的排序操作
常见的两种方式:
- 调用sort()方法,列表中的所有元素默认按照从小到大的顺序进行排序,可以指定reverse=True,进行降序排序
- 调用内置函数sorted(),可以指定reverse=True,进行降序排序,原列表不发生变化
lst = [1,2,54,2,354,2332]
print("原列表:",lst,id(lst))
lst.sort()
print("升序排序后:",lst,id(lst))
lst.sort(reverse=True)
print("降序排序后:",lst,id(lst))
print("---------------------------------使用内置sorted()进行排序---------------------------------------")
lst2 = [131,4314,22,21]
print("原列表",lst2,id(lst2))
lst3 = sorted(lst2)
print("升序排序后:",lst3,id(lst3))
lst4 = sorted(lst2,reverse=True)
print("降序排序后:",lst4,id(lst4))
结果:
原列表: [1, 2, 54, 2, 354, 2332] 186260108480
升序排序后: [1, 2, 2, 54, 354, 2332] 186260108480
降序排序后: [2332, 354, 54, 2, 2, 1] 186260108480
---------------------------------使用内置sorted()进行排序---------------------------------------
原列表 [131, 4314, 22, 21] 186260107392
升序排序后: [21, 22, 131, 4314] 186261180096
降序排序后: [4314, 131, 22, 21] 186260110720
9.8 列表生成式
-
列表生成式:生成列表的公式
-
语法格式:[i1 for i2 in range(1,10)],i1表示列表元素的表达式,i2为自定义变量,range(1,10)表示可迭代对象
-
注意事项:表达列表元素的表达式中通常包含自定义变量
lst = [i for i in range(1,10)] print(lst) lst = [i*i for i in range(1,10)] print(lst)
结果:
[1, 2, 3, 4, 5, 6, 7, 8, 9] [1, 4, 9, 16, 25, 36, 49, 64, 81]
十、字典
10.1 简要介绍
-
字典:Python内置的数据结构之一,与列表一样是一个可变序列,以键值对的方式存储数据,字典是一个无序的序列
-
字典示意图
注:key的值必须为不可变序列
-
字典实现原理:字典的实现原理与查字典类似,查字典是先根据部首或拼音查找汉字对应的页码,Python中的字典是根据可以查找value所在的位置
10.2 字典的创建
-
最常用的方式:花括号
score={'张三':100,'李四':200}
-
使用内置函数dict()
dict(name='python',age=30)
举例:
'''使用{}创建字典'''
ages = {"小米":20,"小花":19,"小兰":29}
print(ages)
print(type(ages))
'''使用dict()创建字典'''
students =dict(name='小名',className='三年级')
print(students)
print(type(students))
'''空字典'''
d={}
print(d)
10.3 字典中元素的获取
- 字典中元素的获取
- [] 举例:ages[‘小米’]
- get()方法 举例:ages.get(‘小米’)
- []和get()取值的不同
- [] 如果字典中不存在指定的key,抛出KeyError异常
- get()方法取值,如果字典中不存在指定的key,并不会抛出KeyError而是返回None,可以通过参数设置默认的value,已便指定的key不存在时返回
ages = {"小米":20,"小花":19,"小兰":29}
print(ages['小米'])
# print(ages['小里']) 报错
print(ages.get('小米'))
print(ages.get('小里'))
print(ages.get('小里',22))
结果:
20
20
None
22
10.4 字典的其他操作
ages = {"小米":20,"小花":19,"小兰":29}
print(ages)
#判断key是否存在
print('小米' in ages)
print('小米' not in ages)
# 删除指定的key-value对
del ages['小米']
print(ages)
#修改字典的元素
ages['小米']=9999
print(ages)
#新增字典的元素
ages['小卡']=30
print(ages)
#清空字典的元素
ages.clear()
print(ages)
结果:
{'小米': 20, '小花': 19, '小兰': 29}
True
False
{'小花': 19, '小兰': 29}
{'小花': 19, '小兰': 29, '小米': 9999}
{'小花': 19, '小兰': 29, '小米': 9999, '小卡': 30}
{}
10.5 获取字典视图的三个方法
- keys() 获取字典中所有的key
- values() 获取字典中所有的value
- items() 获取字典中所有的key-value
ages = {"小米":20,"小花":19,"小兰":29}
keys = ages.keys()
print(keys)
print(type(keys))
values = ages.values()
print(values)
print(type(values))
items = ages.items()
print(items)
print(type(items))
结果:
dict_keys(['小米', '小花', '小兰'])
<class 'dict_keys'>
dict_values([20, 19, 29])
<class 'dict_values'>
dict_items([('小米', 20), ('小花', 19), ('小兰', 29)])
<class 'dict_items'>
10.6 字典的特点
- 字典中所有元素都是一个key-value对,key不允许重复,value可以重复
- 字典中的元素是无序的
- 字典中的key必须是不可变对象
- 字典也可以根据需要动态地进行伸缩
- 字典会浪费较大的内存,是一种使用空间换时间的数据结构
10.7 字典生成式
-
内置函数zip()
用于将可迭代的对象作为参数,将对象中对应的元素打包成一个元组,然后返回由这些元组组成的列表
items = ['apple','orange','peer']
prices = [13,23,25]
d = {items:prices for items,prices in zip(items,prices)}
print(d)
print(type(d))
'''当key和value的个数不相同时,以最少的值为准'''
items = ['apple','orange','peer']
prices = [13,23,25,444,22]
d = {items:prices for items,prices in zip(items,prices)}
print(d)
print(type(d))
结果:
{'apple': 13, 'orange': 23, 'peer': 25}
<class 'dict'>
{'apple': 13, 'orange': 23, 'peer': 25}
<class 'dict'>
十一、元组
11.1 元组的简单介绍
-
元组
Python内置的数据结构之一,是一个不可变序列
-
不可变序列与可变序列
不可变序列:字符串、元组,没有增、删、改操作
可变序列:可以对序列执行增、删、改操作,对象地址不发生更改
11.2 元组的创建
-
直接小括号方式
t=('Python','hello',90)
-
使用内置函数tuple()
t=tuple(('Python','hello',90))
-
只包含一个元组的元素需要使用逗号和小括号
t=(10,)
举例:
'''第一种创建方式,使用()'''
t=('Python','hello',90)
print(t)
print(type(t))
print("---------------------------测试1---------------------------------")
t2='Python','hello',90 #省略小括号
print(t2)
print(type(t2))
print("---------------------------测试2---------------------------------")
t3=('si')
print(t3)
print(type(t3))
print("---------------------------测试3---------------------------------")
t4=('si',) # 只包含一个元组的元素需要使用逗号和小括号
print(t4)
print(type(t4))
print("---------------------------测试4---------------------------------")
'''第二种方式,使用内置函数tuple()'''
t1 = tuple(('Python','hello',90))
print(t1)
print(type(t1))
print("---------------------------测试5---------------------------------")
'''空元组'''
t5 = ()
t6 = tuple()
结果:
('Python', 'hello', 90)
<class 'tuple'>
---------------------------测试1---------------------------------
('Python', 'hello', 90)
<class 'tuple'>
---------------------------测试2---------------------------------
si
<class 'str'>
---------------------------测试3---------------------------------
('si',)
<class 'tuple'>
---------------------------测试4---------------------------------
('Python', 'hello', 90)
<class 'tuple'>
---------------------------测试5---------------------------------
11.3 元组设计成不可变序列的原因
- 在多任务环境下,同时操作对象时不需要加锁,因此,在程序中尽量使用不可变序列
- 注意事项:元组中存储的是对象的引用
- 如果元组中对象本身是不可变对象,则不能再引用其他对象
- 如果元组中对象本身是可变对象,则可变对象的引用不允许改变,但数据可以改变
11.4 元组的遍历
元组是可迭代对象,所以可以使用for…in进行遍历
tup = ('ll',23,'2d')
for item in tup:
print(item)
十二、集合
12.1 集合的简单介绍
集合:
-
Python语言提供的内置数据结构
- 与列表、字典一样都属于可变类型的序列
- 集合是没有value的字典
12.2 集合的创建方式
-
直接使用{}
s={'Python','hello',90}
-
使用内置函数set()
s=set(range(6))
例子:
'''第一种创建方式使用()'''
s={2,3,4,5,6}
print(s)
print(type(s))
'''第二种创建方式使用set()'''
s1=set(range(6))
print(s1,type(s1))
s2=set([1,2,2,4,5,6]) #重复元素会被当成同一个元素进行存储
print(s2,type(s2))
s3=set((1,2,2,4,5,6,65)) #集合中的元素是无序的
print(s3,type(s3))
s4=set("python")
print(s4,type(s4))
s5=set({12,13,34,23})
print(s5,type(s5))
#定义空集合
s6={} #这样定义出来的是空字典
print(type(s6))
s7=set()
print(type(s7))
12.3 集合的相关操作
-
集合元素的判断操作
- in 或 not in
-
集合元素的新增操作
-
调用add()方法,一次添加一个元素
-
调用update()方法至少添加一个元素
-
-
集合元素的删除操作
- 调用remove()方法,一次删除一个指定元素,如果指定的元素不存在则抛出KeyError
- 调用discard()方法,一次删除一个指定元素,如果指定的元素不存在不抛出异常
- 调用pop()方法,一次只删除一个任意元素
- 调用clear()方法,清空集合
举例:
s={1,2,432,432}
print(s,type(s))
print("----------------使用add()方法进行新增-------------------")
s.add(11)
print(s,type(s))
print("---------------------使用update()方法进行新增----------------")
s.update({1,221,33,42,15,46})
print(s,type(s))
print("------------------使用remove()方法进行删除-------------------")
s.remove(1)
print(s,type(s))
print("----------------使用discard()方法进行删除-------------------")
s.discard(2)
print(s,type(s))
print("---------------使用pop()方法进行删除------------------------")
s.pop()
print(s,type(s))
s.pop()
print(s,type(s))
s.pop()
print(s,type(s))
s.pop()
print(s,type(s))
s.pop()
print(s,type(s))
print("--------------使用clear()方法清空集合---------------")
s.clear()
print(s,type(s))
结果为:
{432, 1, 2} <class 'set'>
----------------使用add()方法进行新增-------------------
{432, 1, 2, 11} <class 'set'>
---------------------使用update()方法进行新增----------------
{1, 2, 33, 42, 11, 46, 15, 432, 221} <class 'set'>
------------------使用remove()方法进行删除-------------------
{2, 33, 42, 11, 46, 15, 432, 221} <class 'set'>
----------------使用discard()方法进行删除-------------------
{33, 42, 11, 46, 15, 432, 221} <class 'set'>
---------------使用pop()方法进行删除------------------------
{42, 11, 46, 15, 432, 221} <class 'set'>
{11, 46, 15, 432, 221} <class 'set'>
{46, 15, 432, 221} <class 'set'>
{15, 432, 221} <class 'set'>
{432, 221} <class 'set'>
--------------使用clear()方法清空集合---------------
set() <class 'set'>
12.4 集合间的关系
-
两个集合是否相等
可以使用运算符==或!=进行判断
-
一个集合是否是另一个集合的子集
可以调用方法issubset
-
一个集合是否是另一个集合的超集
可以调用方法issuperset进行判断
-
两个集合是否没有交集
可以调用方法isdisjoint进行判断
举例:
s = {1,2,3,4,5,6,7,8,9,10}
s1 = {2,1,3,5,4,6,7,8,10,9}
s2 = {1,2,3,4}
s3 = {1,3,5,6,11,12,14}
print("-----------------判断两个集合之间是否相等--------------")
print(s==s1)
print("----------------判断一个集合是否是另一个集合的子集--------")
print(s2.issubset(s))
print("----------------判断一个集合是否是另一个集合的超集---------")
print(s.issuperset((s2)))
print("---------------判断两个集合之间是否存在交集--------------")
print(s.isdisjoint(s3)) #没有交集则为True,有则为False
结果:
-----------------判断两个集合之间是否相等--------------
True
----------------判断一个集合是否是另一个集合的子集--------
True
----------------判断一个集合是否是另一个集合的超集---------
True
---------------判断两个集合之间是否存在交集--------------
False
12.5 集合之间的数学操作
举例:
s = {1,2,3,4,6,8,9}
s1 = {6,7,8,10,9}
#交集
print("-----------交集----------")
print(s.intersection(s1),type(s))
print(s & s1)
#并集
print("-----------并集----------")
print(s.union(s1))
print(s | s1)
#差集
print("-----------差集----------")
print(s.difference(s1))
print(s-s1)
print(s1.difference(s))
print(s1-s)
#对称差集
print("-----------对称差集----------")
print(s.symmetric_difference(s1))
print(s^s1)
结果:
-----------交集----------
{8, 9, 6} <class 'set'>
{8, 9, 6}
-----------并集----------
{1, 2, 3, 4, 6, 7, 8, 9, 10}
{1, 2, 3, 4, 6, 7, 8, 9, 10}
-----------差集----------
{1, 2, 3, 4}
{1, 2, 3, 4}
{10, 7}
{10, 7}
-----------对称差集----------
{1, 2, 3, 4, 7, 10}
{1, 2, 3, 4, 7, 10}
12.6 集合生成式
- 含义:用于生成集合的公式
将{}改成[]即为列表生成式,没有元组生成式
十三、列表、字典、元组、集合总结
数据结构 | 是否可变 | 是否重复 | 是否有序 | 定义符号 |
---|---|---|---|---|
列表(list) | 不可变 | 可重复 | 有序 | [] |
元组(tuple) | 不可变 | 可重复 | 有序 | () |
字典 | 可变 | key不可重复 | 无序 | {key:value} |
value可重复 | ||||
集合(set) | 可变 | 不可重复 | 无序 | {} |
十四、字符串的常用操作
14.1 字符串的驻留机制
-
字符串
在Python中字符串是基本数据类型,是一个不可变的字符序列
-
什么叫做字符串驻留机制
仅保存一份相同且不可变字符串的方法,不同的值被存放在字符串的驻留池中,Python的驻留机制对相同的字符串只保留一份拷贝,后续创建相同字符串时,不会开辟新空间,而是把该字符串的地址赋给新创建的变量
-
驻留机制的几种情况(交互模式)
- 字符串长度为0或1时
- 符合标识符的字符串
- 字符串只在编译时进行驻留,而非运行时
- [-5,256]之间的整数数字
-
sys中的intern方法强制2个字符串指向同一个对象
-
PyCharm对字符串进行优化处理
-
字符串驻留机制的优缺点
- 当需要值相同的字符串时,可以直接从字符串池中拿来使用,避免频繁的创建和销毁,提升效率和节约内存,因此拼接字符串和修改字符串是比较影响性能的
- 在需要进行字符串拼接时建议使用str类型的join方法,而非+,因为join()方法是先计算出所有字符串中的长度,然后再拷贝,只new一次对象,效率要比“+”效率高
14.2 字符串的查询操作的方法
功能 | 方法名称 | 作用 |
---|---|---|
查询方法 | index() | 查找子串substr第一次出现的位置,如果查找的子串不存在时,则抛出ValueError |
rindex() | 查找子串substr最后一次出现的位置,如果查找的子串不存在时,则抛出ValueError | |
find() | 查找子串substr第一次出现的位置,如果查找的子串不存在时,则返回-1 | |
rfind() | 查找子串substr最后一次出现的位置,如果查找的子串不存在时,则返回-1 |
例子:
s="hello,hello"
print(s.index("lo")) #3
print(s.find("lo")) #3
print(s.rindex("lo")) #9
print(s.rfind("lo")) #9
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MlKg6Qis-1622990949748)(E:\Typoraimg\img\1622082728633.png)]
14.3 字符串的大小写转换操作方法
功能 | 方法名称 | 作用 |
---|---|---|
大小写转换 | upper() | 把字符串中所有字符都转成大写字母 |
lower() | 把字符串中所有字符都转成小写字母 | |
swapcase() | 把字符串中所有小写字母都转成大写字母,把字符串中所有大写字母都转成小写字母 | |
capitalize() | 把第一个字符转换成大写,把其余字符转换成小写 | |
title() | 把每个单词的第一个字符转换为大写,把每个单词的剩余字符转换为小写 |
14.4 字符串内容对齐操作的方法
功能 | 方法名称 | 作用 |
---|---|---|
字符串对齐 | center() | 居中对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数时是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串 |
ljust() | 左对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数时是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串 | |
rjust() | 右对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数时是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串 | |
zfill() | 右对齐,左边用0填充,该方法只接收一个参数,用于指定字符串的宽度,如果指定的宽度小于等于字符串的长度,返回字符串本身 |
举例:
s="hello,world"
print("------居中对齐-------")
print(s.center(30,'*'))
print("-------左对齐-------")
print(s.ljust(30,"*"))
print(s.ljust(30))
print("------右对齐---------")
print(s.rjust(30,'*'))
print(s.rjust(30))
print("------右对齐--------")
print(s.zfill(30))
print("-333".zfill(9))
结果:
------居中对齐-------
*********hello,world**********
-------左对齐-------
hello,world*******************
hello,world
------右对齐---------
*******************hello,world
hello,world
------右对齐--------
0000000000000000000hello,world
-00000333
14.5 字符串劈分操作的方法
功能 | 方法名称 | 作用 |
---|---|---|
字符串的劈分 | split() | 从字符串的左边开始劈分,默认的劈分字符是空格字符串,返回的值都是一个列表 |
通过参数sep指定劈分字符 | ||
通过参数maxsplit指定劈分字符串时的最大劈分次数,在经过最大次劈分之后,剩余的子串会单独作为一部分 | ||
rsplit() | 从字符串的右边开始劈分,默认的劈分字符是空格字符串,返回的值都是一个列表 | |
通过参数sep指定劈分字符 | ||
通过参数maxsplit指定劈分字符串时的最大劈分次数,在经过最大次劈分之后,剩余的子串会单独作为一部分 |
举例:
s = "hello|world| hello|python"
print(s.split("|"))
print(s.split())
print(s.split("|",maxsplit=1))
print("-------------------------")
print(s.rsplit())
print(s.rsplit("|"))
print(s.rsplit("|",maxsplit=1))
结果:
['hello', 'world', ' hello', 'python']
['hello|world|', 'hello|python']
['hello', 'world| hello|python']
-------------------------
['hello|world|', 'hello|python']
['hello', 'world', ' hello', 'python']
['hello|world| hello', 'python']
14.6 字符串判断的方法
功能 | 方法名称 | 作用 |
---|---|---|
判断字符串的方法 | isidentifier() | 判断指定的字符串是不是合法的标识符 |
isspace() | 判断指定的字符串是否全部由空白字符串组成(回车、换行,水平制表符) | |
isalpha() | 判断指定的字符串是否全部由字母组成 | |
isdecimal() | 判断指定的字符串是否全部由十进制的数字组成 | |
isnumeric() | 判断指定的字符串是否全部由数字组成 | |
isalnum() | 判断指定字符串是否全部由字母和数字组成 |
s="hello,world"
print(s.isidentifier()) # False
s1=" " # 按Tab键形成的空白字符串串
print(s1.isspace()) # True
s2="afd"
s22="张三"
print(s2.isalpha()) # True
print(s22.isalpha()) # True
s3="121"
print(s3.isdecimal()) # True
s4="32423432"
print(s4.isnumeric()) # True
s5="2131da"
print(s5.isalnum()) # True
14.7 字符串的合并和替换
功能 | 方法名称 | 作用 |
---|---|---|
字符串替换 | replace() | 第1个参数指定被替换的子串,第2个参数指定替换子串的字符串,该方法返回替换后得到的字符串,替换前的字符串不发生变化,调用该方法时可以通过第3个参数指定最大替换次数 |
字符串的合并 | join() | 将列表或元组中的字符串合并成一个字符串 |
举例:
s="hello,java,java,java"
print(s.replace("java","Python"))
print(s.replace("java","python",2))
print("|".join(s))
s1=['Java','Python','C++']
print("|".join(s1))
结果:
hello,Python,Python,Python
hello,python,python,java
h|e|l|l|o|,|j|a|v|a|,|j|a|v|a|,|j|a|v|a
Java|Python|C++
14.8 字符串的比较操作
- 运算符:>,>=,<,<=,==,!=
- 比较规则:首先比较两个字符串中的第一个字符串,如果相等则继续比较下一个字符串,依次比较下去,直到两个字符串的字符不相等时,其比较的结果就是两个字符串的比较结果,两个字符串中的所有后续字符将不再被比较
- 比较原理:两个字符进行比较时,比较的是其ordinal value(原始值),调用内置函数ord可以得到指定字符的ordinal value。与内置函数ord对应的是内置函数chr,调用内置函数chr时指定ordinal value可以得到其对应的字符
- ==和is和区别:== 比较的value是否相等,is 比较的是对应的id
14.9 字符串的切片操作
字符串是不可变类型,不具备增、删、改等操作,切片操作将产生新的对象
14.10 格式化字符串
举例:
name="小环"
age=18
print("我的名字叫做%s,年龄%d"%(name,age))
print("我的名字叫做{0},年龄{1}".format(name,age))
print(f"我的名字叫做{name},年龄{age}") #f-string
print("%10d"%10) # 10表示的是宽度
print("%.3f" % 3.22343242) # .3表示是小数点后三位
print('%10.3f' % 3.14321232) #一共总宽度为10,小数点后3位
print('{0:.3}'.format(3.14234324)) #.3 表示的是一共是3位数
print('{0:.3f}'.format(3.14243311)) #.3f表示是3位小数
print('{0:10.3f}'.format(3.14243311)) #同时设置宽度和精度,一共是10位,3位是小数
结果:
我的名字叫做小环,年龄18
我的名字叫做小环,年龄18
我的名字叫做小环,年龄18
10
3.223
3.143
3.14
3.142
3.142
14.11 字符串的编码转换
-
字符串编码转换的原因
-
编码与解码的方式
- **编码:**将字符串转换为二进制数据(bytes)
- **解码:**将bytes类型的数据转换成字符串类型
举例:
s = "你好啊"
# 编码
print(s.encode(encoding="GBK"))
print(s.encode(encoding="UTF-8"))
# 解码
bytes = s.encode(encoding="GBK")
print(bytes.decode(encoding="GBK"))
结果:
b'\xc4\xe3\xba\xc3\xb0\xa1'
b'\xe4\xbd\xa0\xe5\xa5\xbd\xe5\x95\x8a'
你好啊
十五、函数
15.1 函数的简单介绍
-
**函数:**函数就是执行特定任务和完成特定功能的一段代码
-
使用函数的好处
- 复用代码
- 隐藏实现细节
- 提高可维护性
- 提高可读性便于测试
-
函数的创建形式
def 函数名([输入参数]): 函数体 [return xxx]
举例:
def cal(a,b): return a+b print(cal(1,2)) # 3
15.2 函数的参数传递
- 位置传参
- 根据形参对应的位置进行实参传递
- 关键字传参
- 根据形参名称进行实参传递
def cal(a,b):
return a+b
print(cal(1,2)) # 3 位置传参
print(cal(b=10,a=13)) #23 关键字对应传参
15.3 函数的返回值
def fun(num):
odd=[] #存奇数
even=[] #存偶数
for i in num:
if i%2:
odd.append(i)
else:
even.append(i)
return odd,even
lst=[i for i in range(0,20,1)]
print(lst)
print(fun(lst))
'''
函数的返回值
(1)如果函数没有返回值[函数执行完毕之后,不需要给调用处提供数据],return可以省略不写
(2)函数的返回值,如果是1个,直接返回类型
(3)函数的返回值,如果是多个,返回的结果为元组
'''
结果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
([1, 3, 5, 7, 9, 11, 13, 15, 17, 19], [0, 2, 4, 6, 8, 10, 12, 14, 16, 18])
15.4 函数的参数定义
-
函数定义默认值参数
- 函数定义时,给形参设置默认值,只有与默认值不符的时候才需要传递实参
-
个数可变的位置参数
- 定义函数时,可能无法事先确定传递的位置实参的个数时,使用可变的位置参数
- 使用*定义个数可变的位置形参
- 结果为一个元组
def fun(*args): print(args) print(fun(12,123))
-
个数可变的关键字形参
- 定义函数时,可能无法事先确定传递的关键字实参的个数时,使用可变的关键字形参
- 使用**定义个数可变的关键字形参
- 结果为一个字典
def fun(**args): print(args) print(fun(a=10,b=20))
-
注意
- 在函数中,个数可变的位置参数只能有一个,个数可变的关键字参数也只能有一个
- 在一个函数定义过程中,如果既有个数可变的位置参数,又有个数可变的关键字参数,个数可变的位置参数必须放在个数可变的关键字参数之前,否则程序会报错
def fun(*args1,**args2): print(args1)
15.5 函数的参数总结
序号 | 参数的类型 | 函数的定义 | 函数的调用 | 备注 |
---|---|---|---|---|
1 | 位置实参 | √ | ||
将序列中的每个元素都转换为位置实参 | √ | 使用* | ||
2 | 关键字实参 | √ | ||
将字典中的每个键值对都转换为关键字实参 | √ | 使用** | ||
3 | 默认值形参 | √ | ||
4 | 关键字形参 | √ | 使用* | |
5 | 个数可变的位置形参 | √ | 使用* | |
6 | 个数可变的关键字形参 | √ | 使用** |
def fun(a,b,c):
print("a=",a)
print("b=",b)
print("c=",c)
fun(10,20,30)
lst = [10,20,30]
fun(*lst) # * 将序列中的每个元素都转换为位置实参
fun(a=100,b=200,c=300)
dic = {'a':100,'b':200,'c':300}
fun(**dic) # **将字典中的每个键值对都转换为关键字实参
def fun(a,b,*,c,d): #表示从*之后的参数,在函数调用时,只能采用关键字参数传递
print(c,'---',d)
15.6 变量的作用域
- 含义:程序代码能访问该变量的区域
- 根据变量的有效范围可分为:
- 局部变量:在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量就会变成全局变量
- 全局变量:函数体外定义的变量,可作用于函数内外
15.7 递归函数
- **含义:**如果在一个函数的函数体内调用了该函数本身,这个函数就称为递归函数
- **递归的组成部分:**递归调用与递归终止条件
- 递归的调用过程
- 每递归调用一次函数,都会在栈内存分配一个栈帧
- 每执行完一次函数,都会释放相应的空间
- 递归的优缺点
- 缺点:占用内存多,效率低下
- 优点:思路和代码简单
# 递归函数求阶乘
def fac(n):
if n==1:
return 1
else:
return n * fac(n-1)
print(fac(6)) # 结果为720
# 求斐波那契数列的第n位数据
def fibonacci(n):
if n==0:
return 0
elif n==1:
return 1
elif n>=2:
return fibonacci(n-2)+fibonacci(n-1)
# 输出斐波那契数列的前n位数据
for i in range(1,10):
print(fibonacci(i))
十六、Python的异常处理机制
- 方式1
- 方式2
-
方式3
try…execpt…else结构:如果try块中没有抛出异常,则执行else块,如果try中抛出异常,则执行except块
-
方式4
try…execpt…else…finally结构:finally块无论是否发生异常都会被执行,常用来释放try块中释放的资源
-
Python常见的异常类型
序号 异常类型 描述 1 ZeroDivisionError 除(或取模)零(所有数据类型) 2 IndexError 序列中没有此索引(index) 3 KeyError 映射中没有这个键 4 NameError 未声明/初始化对象(没有属性) 5 SyntaxError Python语法错误 6 ValueError 传入无效的参数 -
Python的异常处理机制
-
trackback模块:使用trackback模块打印异常信息
import traceback try: print(1/0) except: traceback.print_exc()
-
十七、类
17.1 类的简单使用与创建
class Person:
# 定义基本属性,写在方法外,称为类属性
name = ''
age = ''
# 定义私有属性,两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__weight。
__weight = ''
'''
1.一个类中不能有两个构造函数.构造函数必须命名为__init__.并且,与Java不同,Python不允许
通过其参数类型重载函数或方法.所以,如果你有两个构造函数,它们都是相同的函数.
2.python中的函数参数在定义时可以有默认值,可以让__init__函数接受多个参数,在后面的一
些参数给出默认值的方法让__init__接受不同个数的参数,并且执行类型检查执行不同的代码,用上述
方法实现类的构造函数的多态性
3.如果不定义构造方法,Python中会有一个默认的构造方法
def _init_(self):
pass
4.self不是python的关键字,可以使用其他单词代替,如
def _init_(a):
pass
'''
def __init__(self,name,age): # 类的构造方法,self代表类的实例
print("My name is",name,",I'm ",age," years old")
'''
定义在类内部,称为类的方法,定义在类的外部,称为函数,与方法的定义有所不同的是,
类的方法定义时必须包含参数 self(可以用其他单词代替self), 且为第一个参数,self 代表的是类的实例,
调用方式:Person.test(person)或person.test() 其中person表示类的实例
'''
def test(self):
print()
'''
使用@staticmethod,表示该方法是静态方法,调用方式,可以直接通过类名.方法名调用,静态方法不要求要包含参数self
'''
@staticmethod
def staticMethod():
pass
'''
使用@classmethod,表示该方法是,classmethod 修饰符对应的方法不需要实例化,不需要 self 参数,但第一个参数
需要是表示自身类的 cls 参数,可以来调用类的属性,类的方法,实例化对象等。
'''
@classmethod
def classMethod(cls):
pass
person = Person("小明",18)
print(person)
Person.staticMethod()
Person.classMethod()
person.staticMethod()
person.classMethod()
person.test()
print("-------------------------------案例测试------------------------------------")
class Man:
place = "上海"
def sayPlace(self):
print(self.place)
def sayPlace():
print("动态绑定方法")
man1 = Man()
man2 = Man()
man1.place = "天津"
man1.sayPlace()
man2.sayPlace()
man2.place = "北京"
Man.place = "深圳"
man1.sayPlace()
man2.sayPlace()
# 动态绑定方法
man2.sayPlace = sayPlace
man2.sayPlace()
17.2 类的高级使用
面向对象三大特征
-
封装:提高程序安全性
- 将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行操作,在类对象的外部调用方法。这样,无需关心方法内部的具体实现细节,从而隔离了复杂度。
- 在Python中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前边使用两个“_”
class Student: def __init__(self,name,age): self.name = name self.__age = age def show(self): print(self.name,self.__age) stu = Student("张三",19) stu.show() ''' 调用私有属性__age的方法 ''' print(dir(stu)) print(stu._Student__age)
-
继承:提高代码的复用性
-
语法格式
class 子类类名(父类1,父类2...): pass
-
如果一个类没有继承任何类,则默认继承object
-
Python支持多继承
-
定义子类时,必须在其构造函数中调用父类的构造函数
class Person(object): #Person继承object类 def __init__(self,name,age): self.name = name self.age = age def info(self): print(self.name,self.age) class Student(Person): def __init__(self,name,age,stu_no): super().__init__(name, age) self.stu_no = stu_no class Teacher(Person): def __init__(self,name,age,teacher_years): super().__init__(name,age) self.teacher_years = teacher_years stu = Student("小明",18,'1001') teacher = Teacher("小花",19,19) stu.info() teacher.info()
-
-
多态:提高程序的可扩展性和可维护性
class Student: def __init__(self): pass def __str__(self): return "重写方法" stu = Student() ''' 注释掉__str__()方法,输出<__main__.Student object at 0x000000AFAF5F3C70>,未注释掉,则输出"重写方法" ''' print(stu)
含义解释:简单的说,多态就是”具有多种形态“,它指的是:即使不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法
class Animal(): def eat(self): print("动物一定需要进食") class Human(Animal): def eat(self): print("人类需要吃饭") class Dog(Animal): def eat(self): print("狗吃骨头") class Cat(Animal): def eat(self): print("猫吃鱼") def fun(animal): animal.eat() fun(Human()) # 人类需要吃饭 fun(Dog()) # 狗吃骨头 fun(Cat()) # 猫吃鱼
静态语言和动态语言关于多态的区别
- 静态语言实现多态的三个必要条件(常见的静态语言:Java)
- 继承
- 方法重写
- 父类引用指向子类对象
- 动态语言的多态崇尚“鸭子类型”,当看到一只鸟走起来像鸭子、游泳起来像鸭子、收起来也像鸭子,那么这只鸟就可以被称为鸭子。在鸭子类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为
特殊方法和特殊属性
名称 | 描述 | |
---|---|---|
特殊属性 | __dict__ | 获得类对象或实例对象所绑定的所有属性和方法的字典 |
特殊方法 | __len__() | 通过重写__len__()方法,让内置函数len()的参数可以是自定义类型 |
__add__() | 通过重写__add__()方法,可使用自定义对象具有“+”功能 | |
__new__() | 用于创建对象 | |
__init__() | 对创建的对象进行初始化 |
class Person:
name = 5
pass
class Student(Person):
pass
class Teacher(Person):
pass
person = Person()
student = Student()
teacher = Teacher()
print(Person.__dict__) # 输出类对象的属性和方法字典
print(person.__dict__) # 输出实例对象的属性字典
print(Person.__bases__) # (<class 'object'>,) 输出类的父类
print(Student.__bases__) # (<class '__main__.Person'>,)
print(Student.__mro__) # (<class '__main__.Student'>, <class '__main__.Person'>, <class 'object'>) 类的层次结构
print(Person.__subclasses__()) #[<class '__main__.Student'>, <class '__main__.Teacher'>] 子类的列表
print('*****************************************************************************************')
a=1
b=2
c = a+b
print(c) # 3
class Test1:
def __init__(self,name):
self.name = name
def __add__(self, other):
return self.name + other.name
def __len__(self):
return len(self.name)
# test1 = Test1("张三")
# test2 = Test1("李四")
# test = test1 + test2 #张三李四 实现两个对象的加法运算(因为在Student类中,编写__add__()特殊的方法)
test3 = Test1(4)
test4 = Test1(2)
print(test3 + test4)
test5 = Test1('long')
print(len(test5)) # 修改__len__()方法,使得默认输出实例对象属性name的长度
类的浅拷贝与深拷贝
-
变量的赋值操作
- 只是形成两个变量,实际还是指向同一个对象
-
浅拷贝
- Python拷贝一般都是浅拷贝,拷贝时,对象包含的子对象内容不拷贝,因此,源对象与拷贝对象会引用同一个子对象
-
深拷贝
- 使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同
class CPU:
pass
class Disk:
pass
class Computer:
def __init__(self, cpu, disk):
self.cpu = cpu
self.disk = disk
# 1.变量的赋值
print("----------变量的赋值-----------------")
cpu1 = CPU()
cpu2 = cpu1
print(cpu1,id(cpu1))
print(cpu2,id(cpu2))
print("----------浅拷贝-----------------")
disk = Disk()
computer = Computer(cpu1,disk)
# 浅拷贝:拷贝时,对象包含的子对象内容不拷贝
import copy
computer2 = copy.copy(computer)
print(computer,computer.cpu,computer.disk)
print(computer2,computer2.cpu,computer2.disk)
print("----------深拷贝-----------------")
# 深拷贝:拷贝时,递归拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同
computer3 = copy.deepcopy(computer)
print(computer,computer.cpu,computer.disk)
print(computer3,computer3.cpu,computer3.disk)
十八、模块
18.1 模块的简要介绍
- 模块英文名称Modules
- 函数与模块之间的关系
- 一个模块中可以包含N多个函数
- 在Python中一个扩展名为.py的文件就是一个模块
- 使用模块的好处
- 方便其他程序和脚本的导入并使用
- 避免函数名的变量名冲突
- 提高代码的可维护性
- 提高代码的可重用性
18.2 自定义模块
-
创建模块
- 新建一个.py文件,名称尽量不要与Python自带的标准模块名称相同
-
导入模块
import 模块名称 [as 别名] from 模块名称 import 函数/变量/类
18.3 以主程序形式运行
在每个模块的定义中都包括一个记录模块名称的变量__name __,程序可以检查该变量,以确定他们在哪个模块中执行。如果一个模块不是被导入到其他程序中执行,那么它可能在解释器的顶级模块中执行。顶级模块的__name__变量的值为__main__
if __name__ == '__main__': # 使用此语句判断当该模块是主程序运行时该运行的语句
pass
18.4 Python中的包
Python中的包
- 包是一个分层次的目录结构,它将一组功能相近的模块组织在一个目录下
- 作用:
- 代码规范
- 避免模块名称冲突
- 包和目录的区别
- 包含__init__.py文件的目录称为包
- 目录里通常不包含__init__.py文件
- 包的导入
- import 包名.模块名
- 注意事项:
- 使用import方式进行导入时,只能跟包名或模块名
- 使用from…import可以导入包、模块、函数、变量
18.5 Python中常用的内置模块
模块名 | 描述 |
---|---|
sys | 与Python解释器及其环境操作相关的标准库 |
time | 提供与时间相关的各种函数的标准库 |
os | 提供了访问操作系统服务功能的标准库 |
calendar | 提供与日期相关的各种函数的标准库 |
urllib | 用于读取来自网上(服务器)的数据标准库 |
json | 用于使用JSON序列化和反序列化对象 |
re | 用于在字符串中执行正则表示式匹配和替换 |
math | 提供标准算数运算函数的标准库 |
decimal | 用于进行精准控制运算精度、有效数位和四舍五入操作的十进制运算 |
logging | 提供了灵活的记录事件、错误、警告和调试信息等日志信息的功能 |
18.6 第三方模块的安装与使用
-
第三方模块的安装
pip install 模块名
-
第三方模块的使用
import 模块名
十九、文件管理
19.1 编码格式
-
常见的字符编码格式
-
Python的解释器使用的是Unicode(内存)
-
.py文件在磁盘上使用UTF-8存储(外存)
-
19.2 文件的读写原理
文件的读写俗称’IO操作’
文件的读写操作,内置函数open()创建文件对象
语法规则
19.3 常用的文件打开模式
- 文件的类型
- 按文件中数据的组织方式,文件分为以下两大类
- 文本文件:存储的是普通“字符”文本,默认为Unicode字符集,可以使用记事本程序打开
- 二进制文件:把数据内容用“字节”进行存储,无法用记事本打开,必须使用专用的软件打开,举例:mp3音频文件,jpg图片文件,doc文档等
- 按文件中数据的组织方式,文件分为以下两大类
打开模式 | 描述 |
---|---|
r | 以只读模式打开文件,文件的指针将会放在文件的开头 |
w | 以只写模式打开文件,如果文件不存在则创建,如果文件存在,则覆盖原有内容,文件指针在文件的开头 |
a | 以追加模式打开文件,如果文件不存在则创建,文件指针在文件开头,如果文件存在,则在文件末尾追加内容,文件指针在原文件末尾 |
b | 以二进制方式打开文件,不能单独使用,需要与其他模式一起使用,rb,或者wb |
+ | 以读写方式打开文件,不能单独使用,需要与其他模式一起使用,a+ |
19.4 文件对象的常用方法
方法名 | 说明 |
---|---|
read([size]) | 从文件中读取size个字节或字符的内容返回,若省略[size],则读取到文件末尾,即一次读取文件所有内容 |
readline() | 从文本文件中读取一行内容 |
readlines() | 把文本文件中每一行都作为独立的字符串对象,并将这些对象放入列表返回 |
write(str) | 将字符串str内容写入文件 |
writelines(s_list) | 将字符串列表s_list写入文本文件,不添加换行符 |
seek(offset[,whence]) | 把文件指针移动到新的位置,offset表示相对于whence的位置: offset:为正往结束方向移动,为负往开始方向移动,whence不同的值代表不同的含义: 0:从文件头开始计算(默认值) 1:从当前位置开始计算 2:从文件末尾开始计算 |
tell() | 返回文件指针的当前位置 |
flush() | 把缓冲区的内容写入文件,但不关闭文件 |
close() | 把缓冲区的内容写入文件,同时关闭文件,释放文件对象相关资源 |
19.5 with语句(上下文管理器)
- with语句可以自动管理上下文资源,不论什么原因跳出with块,都能确保文件正确的关闭,以此来达到释放资源的目的
'''
文件的复制
'''
with open('demo03.py','rb') as src_file:
with open('demo03_copy.py','wb') as target_file:
target_file.write(src_file.read())
'''
MyContentMgr实现了特殊方法__enter__(),__exit__()称为该类对象遵守了上下文管理器协议
该类对象的实例对象,称为上下文管理器
'''
class MyContentMgr(object):
def __enter__(self):
print('enter方法被调用执行了')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('exit方法被调用执行了')
return self
def show(self):
print(1/0)
with MyContentMgr() as file:
file.show()
19.6 目录操作
-
os模块是Python内置的与操作系统功能和文件系统相关的模块,该模块中的语句的执行结果通常与操作系统有关,在不同的操作系统上运行,得到的结果可能不一样
-
os模块与os.path模块用于对目录或文件进行操作
import os # os.system('notepad.exe') #打开记事本 # os.system('calc.exe') # 打开计算器 # 直接调用可执行文件 os.system('D:\Tencent\QQ\Bin\QQScLauncher.exe') # 打开QQ
-
os模块操作目录相关函数
函数 说明 getcwd() 返回当前的工作目录 listdir(path) 返回指定路径下的文件和目录信息 mkdir(path[,mode]) 创建目录 makedirs(path1/path2…[,mode]) 创建多级目录 rmdir(path) 删除目录 removedirs(path1/path2…) 删除多级目录 chdir(path) 将path设置为当前工作目录 -
os.path模块操作
函数 说明 abspath(path) 用于获取文件或目录的绝对路径 exists(path) 用于判断文件或目录是否存在,如果存在返回True,否则返回False join(path,name) 将目录与目录或者文件名拼接起来 splitext() 分离文件名和扩展名 basename(path) 从一个路径中提取文件路径,不包括文件名 isdir(path) 用于判断是否为路径