Python语法梳理-1.0
Python
- Python基础语法:标识符,关键字,变量,判断循环 。。。。
- 容器类型(数据类型中的高级类型)
- 函数
- 文件处理
- 面向对象
- 包和模块
- 异常处理
1、Python概述
- 创始人:吉多·范罗苏姆 龟叔
- 为什么要学习Python:大势所趋,简单易学,使用范围广
- 我们本次学习使用Python3.x版本
- Python在大数据生态中应用非常广泛
2、Python解释器和pycharmIDE工具
- Python解释器是将Python代码解释为机器语言(二进制文件)的一种工具
- Python代码必须经过解释器解释,计算机才能够去执行命令
- 常见的解释器版本:
- CPython: 官方版本,稳定,持续更新
- Ipython:可交互,在CPython基础上进行了升级
- pypy:使用Python编写的解释器
- JPython:使用java编写的解释器,可以将Python便以为字节码文件,在java平台上运行
- pycharm IDE:
- 语法高亮
- 工程管理
- 代码提示
- 错误检查
- 。。。。。。。
- pychram基本设置
- 主题:file — settings—在搜索栏搜索 theme —-修改主题
- 字体:file — settings – 在搜索栏输入font —- 修改字体
- 修改解释器:file — project:项目名称— Python interpreter –修改解释器
- 工程管理:file – open —选择工程
- this windows : 在当前窗口打开
- new windows:在新窗口打开
- attach :合并项目窗口
- 关闭工程: file – close project
3、Python中的注释
- 单行注释: # 注释的内容
- 可以在语句末尾注释
- 快捷键:ctrl+ /
- 多行注释:三对单引号,或者三对双引号
- 可以在注释内部换行
1 | """ |
4、变量
- 变量特性:
- 容器
- 临时
- 可变
- 变量定义的格式:
- 变量名 = 值
- 标识符的命名规则:
- 只能是数字字母下划线组成
- 首字母不能是数字
- 严格区分大小写
- 不能是关键字
- 在Python中定义变量必须赋值,否则报错
1 | # 牛奶和可乐交换的案例 |
5、标识符的命名规范
- 见名知意
- 类名使用大驼峰命名法
- ClassName
- 变量名,函数名,包名,模块名使用下划线命名法
- class_name
1 | # 要见名知意 |
6、变量的使用
- 定义:变量名 = 值
- 调用:函数(变量名) 或者 使用变量名进行运算 变量名1 + 变量名2
- 变量必须先定义后调用
1 | # 使用变量直接调用变量名即可,我们使用的是变量名,参与执行和运算的是变量中的数据(值) |
7、Python中的数据类型
- int 整型
- float 浮点型
- bool 布尔型
- str 字符型 字符串
- list 列表
- tuple 元组
- set 集合
- dict 字典
- 查看数据类型使用的函数是 type()
1 | # 数据类型查看的函数 type(数据/变量名) |
8、Python中的bug和调试
- 常见的bug类型:
1 | # 常见的bug |
- bug调试工具的使用
- 打断点:在行号后边点击出现小红点
- 右键debug进入调试模式,代码执行暂停到断点位置代码执行之前
- debugger :查看参数及变量在执行过程中的变化情况
- console:查看控制台输出内容
- step over:单步执行代码
- resume :执行到下一次断点位置或者程序结束
- stop:让程序终止
9、字符串的格式化及输出
- 格式化是字符串所具有的功能,与print无关,哪怕不进行输出,也可以进行字符串的格式化
1 | # 字符串格式化 :格式化是字符串所具有的功能 |
- 格式:
- 单占位符:’要书写的内容,占位符’ % 变量名
- 多占位符: ‘要书写的内容,占位符1, 占位符2, 。。。。’ % (变量1, 变量2,。。。。)
- %之前的占位符数量要和%之后的变量数量相匹配,一一对应否则会报错
1 | # 格式: '字符串,占位符' % 变量 |
1、转译字符
- \n:换行符
- \t:制表符
- %%:在字符串格式化拼接时输出%
1 | # \n 换行符 |
2、f-string
- f-string是Python3.6之后出现的格式化语法
- 格式:f’要输出的字符串{要拼接的变量}’
- f可以是大写,也可以是小写,
- 引号可以是单引号,也可以是双引号
- 精度控制
- {浮点型变量:.nf} 保留n位小数,四舍五入
- {整型变量:0nd} 保留n位,不足位用0补齐,如果超出则原样显示
- %可以单独输出
1 | # f-string是Python3.6以后推出的格式化方式 |
3、数据类型转换
数据类型转换是为了不同类型数据之间可以进行拼接或运算
格式:数据类型(要转化类型的变量或值)
int和float类型直接可以随意转换
- float转换为int类型只保留整数部分
- int转换为float类型在末尾添加。0
如果数值型转换为str类型,可以随意转换
如果str类型转换为数值型
- float 必须保证str引号内部是浮点型数据或整型数据
- int 必须保证str引号内部是整型数据
1 | # 需求: 在超市中有两种水果,苹果和橘子 |
4、算数运算符
+ - * / // % **
//
取商%
取余**
幂次运算
1 | # + - * / % // ** |
结论算数运算符优先级: + - < * / // % < **
如果忘记了也没关系使用()提高运算符优先级即可
1 | print(1 + 2 * 3) |
5、赋值符号
- = :将等号右侧的值赋值给等号左侧的变量
- 可以给单个变量赋值: 变量= 值
- 可以给多个变量赋不同的值 : 变量1, 变量2. 变量3 = 值1, 值2, 值3
- 可以给多个变量赋相同的值:变量1 = 变量2 = 变量3 = 值
1 | # = (在Python中等号不是判断相等的而是赋值使用) |
6、复合赋值运算符
- ```
+= -= *= /= //= %= **=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
- 复合赋值运算符等号左侧一定是已经被定义的变量
- 复合赋值运算符右侧是已经被定义的变量或者值
```python
# += -= *= /= //= %= **=
a = 1
# a += 1 >>> a = a + 1 将a中的变量取出与1相加得到的数值赋值给a
a += 1
print(a)
# 符合赋值运算符等号左侧只能是已经定义的变量
# 符合赋值运算符等号右侧可以是已经定义的变量或者值
# NameError: name 'b' is not defined
# b必须已经被定义 b = b - 1 先计算b - 1 此时b必须存在
# b -= 1
# print(b)
# 复合赋值运算符不能连续使用
# a += 1 += 2
# 练习
a = 2
a *= 2
print(a)
b = 12
b //= 5
print(b)
7、比较运算
< > <= >= == !=
- 比较运算就是比较数据值的大小
- 比较运算可以连续使用
- 比较运算中比较相等使用== 而 不能使用 = (赋值运算符)
1 | # < > <= >= != == |
8、逻辑运算
- and 同真即真
- or 同假即假
- not 真变假 假变真
1 | # and 同真即真 |
9、短路运算
1 | # 短路运算: |
10、分支语句
- 单一条件判断
1 | if 条件: |
- 对立条件判断
1 | if 条件: |
- 多条件判断
1 | if 条件1: |
- 注意事项:
- 分支语句中条件可以是bool值或者能够转换为bool值的数据或者表达式
- 分支语句中只能执行其中一个分支的命令,如果一个条件符合则后续条件均不会进行判断
1 | # 什么样的内容可以作为条件出现? |
11、分支语句嵌套
- 在分支语句中包含其他分支语句
1 | # 嵌套:在if语句控制的代码块中存在其他的if语句 |
12、猜拳游戏
1 | # 需求: |
13、三目运算
- 格式:条件成立时返回的数据 if 条件 else 条件不成立时返回的数据
1 | # 三元运算符又叫三目运算 |
1、循环介绍
- 有条件的重复做相似的事情
- Python中循环分为while 和for
2、while循环的使用
格式: while 条件: 循环体
while 循环的三个必要元素
- while 关键字
- 循环条件
- 循环体
构造循环要想的四件事
- 初始状态
- 循环条件
- 要重复做的事情
- 循环控制
案例
1 | # 需求:求1-100的累加和 |
1 | # 需求:输出10以内的所有奇数 |
1 | # 需求: 1-100的偶数累加和 |
3、continue和break
- continue :跳出本次循环,进入下一次循环
1 | # continue: 跳出本次循环,继续执行下一次循环(不会影响循环的次数) |
- break : 结束当前循环,后续循环次数不再执行
1 | # break:跳出循环,终止此次循环之后的所有循环 |
- break 和continue 只能在循环体中使用
4、死循环
- 死循环不是bug,是程序的一种特殊运行状态,程序员可以用死循环做很多事情
- 死循环就是循环条件永远满足的一种循环
1 | # 什么是死循环? 循环条件永远满足,可以持续循环的代码 |
5、循环嵌套
- 循环体中包含其他循环结构的状态叫做循环嵌套
- 外层循环执行一次,内层循环将全部执行完成
1 | # 需求:锻炼身体:跑步四圈,做深蹲10分钟,此为一组训练,要做三组 |
- 注意:break 和continue 控制的是当前所在的循环结构
1 | # 需求:锻炼身体:跑步四圈,做深蹲10分钟,此为一组训练,要做三组 |
6、循环嵌套案例:
1 | # 需求:打印五行五列的一个*组成的矩形 |
1 | # 使用while语句打印三角形,第一行一个* 第二行两个* ..... |
1 | # 使用while循环的嵌套打印九九乘法表 |
7、for循环
- for循环时遍历数据序列,每次获取一个元素,直到元素全部被获取,结束循环。
1 | # for循环的语法结构 |
8、for循环中的break 和continue
- 和while循环中使用方法一致
- break:打破循环,后续循环不再执行
- continue: 结束本次循环,进入下一次循环,不会影响循环次数
1 | # break 打破循环,后续循环不会执行 |
9、for循环嵌套
1 | # 打印一个直角三角形 |
1、循环中的else
- for…else…
- while…esle…
- 如果循环正常结束,则执行else中的代码,如果循环异常结束,不执行else中的代码
- break 可以打破循环造成循环异常结束
- continue不会造成循环异常结束
1 | # 语法结构 |
1 | # 语法结构 |
2、字符串的定义以及输入输出
- 字符串定义方式
- 一对单引号
- 一对双引号
- 三对单引号
- 三对双引号
- 如果我们想输出单引号或者双引号,直接在最外层包裹其他的字符串定义形式即可
- 输入: input
- 输出:print
- 字符串可以进行格式化处理: f-string 传统占位符形式拼接
1 | # 字符串的定义方式 |
1 | # 输入 input |
3、字符串索引
- 索引就是系统给字符串中每一个元素的编号
- 正数索引:从0开始,从左至右依次递增
- 负数索引:从-1来时,从右至左依次递减
- 使用索引可以获取字符串中的元素
- 字符串[元素的索引]
1 | # 什么是字符串索引? |
4、字符串切片
- 字符串切片就是讲字符串中的一部分数据按照指定规则进行分隔得到的新的字符串
- 字符串切片的格式
1 | 字符串[起始位置索引:终止位置索引:步长] |
- 起始位置可以省略:
- 步长为正:起始位置默认为字符串开始
- 步长为负:起始位置默认为字符串结束
- 终止位置可以省略:
- 步长为正:终止位置默认为字符串结束
- 步长为负:终止位置默认为字符串开始
- 步长可以省略,省略后默认为1,并且可以省略冒号
- 复制字符串:str[:]
- 反转字符串:str[::-1]
- 注意:如果步长为正,则起始位置在终止位置左侧,如果步长为负,则起始位置在终止位置右侧
1 | # 切片:就是按照一定的索引位置和步长将字符串分割出一部分就是切片 |
5、字符串查询
- index:查找字符串中子字符串所在位置i,如果有该字符串,查询其==从左至右==第一次出现的位置的正数索引,==否则报错==。
- find:查找字符串中子字符串所在位置i,如果有该字符串,查询其==从左至右==第一次出现的位置的正数索引,==否则返回-1==。
- rindex:查找字符串中子字符串所在位置i,如果有该字符串,查询其==从右至左==第一次出现的位置的正数索引,==否则报错==。
- rfind:查找字符串中子字符串所在位置i,如果有该字符串,查询其==从右至左==第一次出现的位置的正数索引,==否则返回-1==。
- count:查询子字符串在指定字符串中出现的次数。
1 | str1 = 'hello python' |
6、字符串替换
- replace:将旧值替换指定字符串中的新值
1 | # replace |
7、字符串的拆分和合并
- split:字符串按照指定分隔符进行拆分
- 拆分后得到的结果是有拆分后的字符串组成的一个列表
- 拆分后,所有的分隔符消失
- join:将字符串序列(容器类型中所有元素均为字符串)按照指定分隔符进行合并
1 | # split 字符串拆分 |
8、字符串转换
- capitalize:将字符串首字母大写,其余字母小写
- title: 将字符串中每个单词首字母大写(任何非字母字符都可以作为单词分隔符)
- upper:将字符全部变为大写
- lower:将字符全部变为小写
1 | # 字符串中各种大小写转换 |
9、字符串两侧指定字符删除
- strip:删除字符串两侧的指定字符
- rstrip:删除字符串右侧的制定字符
- lstrip:删除字符串左侧的指定字符
1 | # strip 去重字符串左右两侧指定字符 |
10、字符串对齐
- rjust:右对齐
- ljust:左对齐
- cneter: 居中对齐
1 | str1 = 'python' |
11、字符串判断
- 所有的字符串判断结果都是布尔型数据
- isalnum:判断是否都为字母或数字
- isalpha:判断是否都为字母
- isdigit:判断是否都为数字
- isspace:判断是否都为空格
- endswith:是否以。。结尾
- startswith:是否以。。开头
- 其余内容自己测试学习
1 | # 判断字符串内的数据是否符合某种规则 |
1、列表的查询
- index:从左至右查询元素在列表中所处的位置,如果查询到该元素返回其第一次出现所在位置的正向下标,如果不存在则报错
- count:查询指定元素在列表中出现的次数
- in:查询指定元素是否在列表中
- not in:查询指定元素是否不在列表中
1 | # 索引查询 |
2、列表的增加
- append: 在类表的末尾追加数据
- extend:将数据序列进行迭代依次提取出每一个元素添加到列表末尾
- insert:在指定位置追加数据元素
1 | # append 在列表末尾追加数据 |
3、列表中的删除
del 先对列表中的元素进行查找(使用下标),找到后使用del删除
pop:删除类表中指定下标位置的元素,如果不指定默认删除最后一个,并且返回被删除的值
remove:删除指定值的下标,只删除丛左至右的第一次出现的该值元素
clear:清空列表,和重新赋值为空有逻辑上的区别。
1 | # del 将数据引用切断 |
4、列表的修改
- 使用索引修改: 列表[索引] = 新值
- 查询列表索引值必须在列表中存在
- reverse: 列表的反转
- sort:列表的排序,默认为升序
- reverse:可以进行列表倒排,降序
- key:添加函数,使排序规则更加复杂多变
1 | # 通过索引进行修改 |
5、列表遍历
- for遍历
- while遍历
1 | # while遍历列表 |
6、列表的嵌套
- 列表中嵌套其他的子列表,就是列表的嵌套
- 嵌套后的列表可以使用循环嵌套来进行遍历
1 | # 列表的嵌套: 在一个列表中包含其他的列表元素 |
7、元组的定义
- 单元素元组: 变量 = (数据,)
- 多元素元组:变量 = (数据1, 数据2, 数据3….)
1 | # 元组:可以储存多个数据,但是元组内的数据不能被修改(元定义后只能被查询) |
8、元组的相关操作
- 元组中的数据不能增删改,所以只能查询
- 元组的查询方式
- 索引查询:和列表的使用方式一致
- index :从左至右查询指定元素在元组中第一次出现的位置索引,如果存在则返回正向索引,如果不存在则报错
- count:查询指定元素在元组中出现的次数
- len:查询元组的长度:也就是查询元组中元素的个数
1 | # 元组的增删改:由于元组中的数据不可修改,所以元组中的数据不能进行增删改操作 |
9、字典的定义
- 格式:变量 = {key1 : value1, key2: value2……}
- 空字典定义:
- {}
- dict()
- 字典中键不能重复,是唯一的,但是值可以重复
- 字典中的键要见名知意,体现字典可以见名知意的特性
1 | # 字典:储存多个数据,以键值对形式存储,方便快速存取 |
10、字典的增加
- 字典[新的key] = 值
- 如果key在原字典中已经存在则为修改原key对应的值
1 | # 增 使用新的键 = 值的形式增加键值对 |
11、字典的删除
- del 查找到字典的键所对应的值进行删除
- clear()清空字典所在数据空间中的多有键值对
- pop:删除指定键所对应的键值对,会将删除的键值对所对应的值进行返回
- popitem: 删除随机一个键值对,尝试后发现总是删除最后一个,会将删除的键值对以元组的形式进行返回
1 | # del |
12、字典的修改
- 字典[key] = 值
- 字典中key必须存在
- update:
- update(键 = 值)
- update({键:值})
- 对应的键一定存在
1 | # 通过索引修改字典中的键值对 |
13、字典的查询
- 使用键查询值:字典[key]
- 查询的键不存在时则报错
- get:字典.get(key)
- 查询的键不存在时,不报错,可以默认返回None,或者手动设置返回内容
- keys:获取所有的键
- values:获取所有的值
- items:获取所有的键值对组成的元组
1 | # 直接使用key进行查询 |
14、字典的遍历
1 | # 字典的遍历 |
15、集合的定义
- 变量 = {数据1, 数据2, 数据3.。。。}
- 空集合:set()
- 集合是一个无序的 不重复的数据序列
1 | # 集合: 集合是一个无序,不重复的数据序列 |
16、集合的相关操作
- 集合的增加
- add:添加一个元素,如果值已存在,则去重
- update: 更新元素(在括号中添加可迭代类型),如果值已存在则去重
1 | # add 增加 |
- 集合的删除
- remove:根据元素值进行删除,如果元素不存在则报错
- discard:根据元素值进行删除,如果元素值不存在则不报错
- pop:删除任意元素,并返回被删除的值
1 | # remove |
- 集合判断:
- in
- not in
1 | # 数据是否在集合中 |
- 集合可以使用for循环遍历,但是遍历顺序随机
1 | # for 遍历 |
1、不定长参数
- 位置不定长参数(*args):多余的位置参数,可以被args接收,并且打包为一个元组,保存在args当中。
1 | # 不定长参数主要就是在定义函数时,不确定参数的个数时即可进行不定长参数的书写 |
- 关键字不定长参数(**kwargs):将多余的关键字 参数,打包为一个字典,保存在kwargs当中
1 | # 关键字不定长参数,可以接收多个未定义参数的关键字赋值 |
2、函数定义和调用时各类参数的排布顺序
- 形参: 位置参数》》位置不定长参数》》缺省参数》》关键字不定长参数
- 实参:顺序赋值》》关键字参数赋值
- 在开发中除非有特殊需求,一般参数种类不超过三种,参数个数不超过5个,如果种类或数量太多,会造成我们开发中沟通成本加大
1 | # 在定义函数时:位置参数,缺省参数,位置不定长参数,关键字不定长参数 到底在定义时怎么排列呢? |
3、组包和拆包
- 组包:将多个数据,组合为一个容器类型,进行使用或变量保存
- 拆包:将一个容器类型,进行拆分,其中的每一个元组赋值给其他的变量
1 | # 组包:就是讲多个值进行组合,打包为一个容器类型的过程 |
4、引用
- 数据的三个维度:值, 数据类型,唯一标识
- 值: 数据计算时使用的值
- 数据类型:数据的存储类型
- 唯一标识:id ,也就是数据的内存地址的标识
- 如果我们想要判断id 或者说唯一标识是否相等,我们使用is进行判断
1 | # 在Python中所有的数据分为三个维度: 值(判断==), 数据类型(int...float...), 唯一标识(id) |
5、可变类型和不可变类型
- 可变类型:内存空间中的数据可以被修改的数据类型
- list set dict
- 不可变数据类型:内存空间中的数据不可以被修改的数据类型
- int float bool str tuple
1 | # 传参或者变量的传递是进行了值的传递 还是进行了引用地址的传递呢? |
6、引用当做参数传递
- 在函数传参过程中,变量会以引用的形式进行传参,也就是说我们的变量或参数传递是引用传递,不是值传递
- 如果参数是可变数据类型,那么在函数内修改其引用地址指向空间内的数据,外部数据同时发生变化
- 如果参数是不可变数据类型,其实也是引用传递,只不过引用地址指向的数据空间中的数据无法被修改
1 | # 将数字1所在空间的引用地址赋值给了a |
7、学生管理系统
1 | # 需求拆分: |
8、函数递归
- 函数内部调用函数本身
- 函数有明确的递归跳出条件
- 不超出最大调用深度
1 | # 函数递归的三个必备条件 |
9、lambda函数
- 匿名函数,在函数定义时没有函数名
- 可以用变量保存,在变量之后添加括号即可调用
1 | # lambda表达式,也叫匿名函数 |
1、文件的基本操作
- 文件打开的格式:
- file = open(文件路径,读写模式)
- 文件路径:可以写相对路径,也可以写绝对路径
- 读写模式:r(读取) w(写入) a(追加)
- file = open(文件路径,读写模式)
- 文件打开后,必须关闭,否则持续消耗服务器性能。
1 | # 文件读写,在使用的时候和我们正常使用文件一样 |
2、文件的读取操作
- read:如果()内填写数字,则读取指定字符的字符串,每次读取指定字符,在一个文件开启后,多次读取会持续向后读取字符,如果字符全部读取完成将会返回空字符串“”
- 格式: 文件对象.read(单次最大读取字符数)
- 如果读取的文件不存在则直接报错
1 | # 文件在'r'模式下可以进行文件读取 |
readline: 每次读取一行数据,以\n为分隔符,在一个文件开启后,多次执行读取操作会持续向后读取,如果字符全部被读取完成,则返回空字符串“”
- 格式:文件对象.readline()
readlines:一次性将文件全部读取,读取后,将文字以一行为一个元素保存到列表当中进行返回
- 文件对象.readlines()
1 | # 除了read外还有一些读取方式 |
3、文件的写入操作
- 使用写入模式‘w’打开文件
- 如果文件存在,则清空源数据
- 如果文件不存在,则新建文件,不会报错
- 使用write可以写入字符
- 在windows电脑中书写文件读写时,需要使用encoding进行编码格式指定
- 格式:open(文件路径, 读写模式, encoding = 编码格式)
1 | # write 写入 |
4、文件的追加操作
- ‘a’:模式下进行文件打开
- 如果文件不存在,则创建新文件
- 如果文件存在,则在原有文件内进行字符串追加,不会清空源文件
- 在追加模式下,也是使用write进行文件写入,没有单独的追加方法,写入方式和‘w’模式一致
1 | # 'a'模式写入:追加模式 |
5、文件读写模式拓展(了解,看到能明白意思即可)
a: a a + ab ab+
- a:字符追加模式
- a+ :字符追加模式下可以进行字符读取
- ab:字节追加
- ab+:字节追加模式下,可以进行字节读取
w: w w + wb wb+
- w:字符写入模式
- w+:字符写入模式下可以进行字符读取
- wb:字节写入模式
- wb+:字节写入模式下,可以进行字节读取
r: r r + rb rb+
- r:字符读取模式
- r+:字符读取模式下可以进行字符写入
- rb:字节读取模式
- rb+:字节读取模式下,可以进行字节写入
6、文件备份案例
1 | # 需求:用户输入一个文件名,通过文件读写操作进行文件备份,并且将备份文件名称更改为:源文件名[备份].后缀 |
7、rename和remove
- rename可以进行文件的重命名或文件移动
- remove 可以进行文件删除
1 | # 如果想要使用这两个方法,就要去进行模块导入 |
8、文件夹的操作
- mkdir:创建一个空文件夹,不能创建多级文件夹
- rmdir:删除空文件夹,不能删除有文件的文件夹
- getcwd:获取当前使用的工作目录的路径
- chdir:切换当前的工作目录
- listdir:查询指定目录的目录结构,将该目录下所有文件名以字符串形式保存在列表中进行返回
- 括号内不填写任何内容则为查询工作目录的目录结构
- 如果填写路径,则是对指定目录的查询
1 | # 在使用下方函数或方法时,需要先导入os模块方可使用 |
9、批量修改文件名案例
1 | # 需求:批量修改指定目录下所有文件的文件名 |
10、面向对象的思维方式
- 面向对象,是一个编程思想,并不是一项技术,重在理解
- 面向过程:一步一步的完成功能:自上而下,逐步细化
- 面向对象:找到或者构造一个可以完成功能的主体:找到实体,功能完备
11、类和对象
- 类就是一系列拥有相同或相似功能的对象的集合,或者说类就是一系列事物的统称
- 对象就是类的具体的表现形式
1 | 1、手机是对象还是类? |
12、类的定义
- 经典类
- class 类名:
- 新式类
- class 类名(父类名):
1 | # 定义一个类: |
13.类的实例化
- 类的实例化又叫做创建对象
- 类中实例化后的对象可以调用类中的方法
- 一个类理论上可以实例化无数个对象
- 格式: 类名()
1 | # 类的实例化又称为创建对象 |
14、self
- self就是讲调用方法的实例传入方法内部,在方法内部可以调用实例的属性和方法
1 | # 在类的内部定义方法的时候,自动传入一个self |
1、实例属性的添加和获取
- 在类的外部添加和获取实例属性
- 添加:对象名.属性名 = 值
- 获取:对象名.属性名
- 创建对象后,我们对其中一个对象添加实例属性,其他对象不发生变化
1 | # 在类的外部可以添加或获取实例属性 |
- 在类的内部添加和获取实例属性
- 添加:self.属性名 = 值
- 获取:self.属性名
- 一般实例属性写在实例方法中,调用该方法才能获取实例属性,对象创建后,其中一个实例调用该方法,获取实例属性,其余对象不发生变化
1 | # 实例属性在类的内部添加或获取的格式 |
2、__init__()
方法
__init__()
方法在对象创建完成后,初始化对象时,自动调用- 在init方法中添加的属性,由于每个对象都会执行该方法,所以都包含该属性,被称之为共有属性
- 在init方法之外添加的属性,由于不是每个对象都拥有,所以被称之为独有属性
1 | # __init__():在对象创建完成后,初始化对象过程中自动调用的方法 |
3、带参数的__init__()
方法
- init方法在对象被创建时,可以将“类名()”这里边括号添加的参数传递到init方法内部
- 在接收到参数时,可以动态给对象添加实例属性
- 如果init方法添加了参数,那么在创建对象时,必须给其赋值,否则报错
1 | # 每次我们创建对象时,如果使用init方法,是不是只能添加同一个值的属性呢? |
4、__str__()
方法
- 在类的内部实现
__str__()
方法,他会在我们讲对象转换为str类型时自动调用,返回其return内的数据 - str方法内只能返回str类型的数据
- str方法自动调用的场景
- 强制类型转换: str(对象)
- ==隐式==类型转换: %s作为占位符接收对象,或者 print打印等,都会自动调用
1 | # __str__()方法是在数据被转换为str类型时自动调用的方法 |
5、__del__()
方法
- 对象被释放前,自动执行
__del__()
方法 - 释放对象的几个场景
- 出了函数作用域后,局部变量被释放
- 程序执行完成后,所有变量被释放
- 执行del操作后,可以提前释放变量
1 | # 之前我们学过del操作 |
6、面向对象案例
1 | ''' |
7、单继承
- 单继承就是某个类只继承自一个父类,同时,继承关系中可以有多级继承
- 继承过程中,子类可以使用父类的所有非私有属性或方法
- 如果父类或更高级的父类,实现了init方法,并且进行了参数设定,实例化子类对象时必须传值
1 | # 单继承:一个子类,只继承一个父类,并且可以多级继承 |
8、多继承
一个子类,继承多个父类的过程就是多继承
在多继承中,子类可以调用多个父类中的非私有方法或者属性
多继承中,如果出现同名属性或方法,优先调用继承位置靠前的父类中的方法或属性
1 | # 多继承:一个类定义时,继承了多个父类,同时可以使用多个父类中的方法或者属性 |
9、子类中重写父类方法
- 子类中重写父类方法,则调用方法时,直接调用子类中的方法,不会调用父类的
- 重写时只要方法名称相等即可,不需要进行参数的校对
- 为什么可以重写父类方法,因为在调用方法或者属性时,会按照继承层级依次查找
1 | # 定义一个Person类 |
1、在子类中调用父类方法
super().方法名()
类名.方法名(self)
spuer(要从哪一个类的上一级类开始查找, self).方法名()
子类调用父类方法时,一般都是想对父类方法进行扩展
1 | class Person(object): |
2、多态
- 在继承链条中,子类重写父类方法,即多个子类和父类中都拥有同名方法,将其对象传入函数或方法内部,执行相同方法后,所展示的效果完全不同,这种现象叫做多态
1 | class Person(object): |
3、类属性
- 类属性,就是所有的对象所共有的属性,在对其修改够,所有对象的类属性放生了改变
- 实例属性,每个对象所独有的,对象被创建后,添加修改实例属性,对其他对象不产生影响
1 | # 类属性 ,有些地方也叫类变量 就是在类中创建的属于所有对象的属性 |
4、类方法
- 如果在方法内部不需要使用实例属性和实例方法,但是需要使用类属性或者类方法我们就定义类方法
- 定义方式:需要在方法上方写@classmethod
- 在类方法中会自动传入cls,这个参数代表的是当前类本身
1 | class Apple(object): |
5、静态方法
- 既不依赖于实例,也不依赖于类,这种方法我们就可以定义为静态方法
1 | class Person(object): |
6、面向对象案例
1 | # 需求: 进行游戏 |
7、异常捕获
- 使用try和except可以捕获异常,也就是在出现异常后不会将代码终止运行,而是执行except中的代码处理异常
1 | # 异常捕获:通过代码将可能出现异常的文件放入try中,然后如果出现异常就执行except中的命令 |
8、捕获指定类型的异常
- 在except后边添加异常类型,就可以捕获指定类型的异常
- 如果我们想要捕获多种异常
- 可以在except后边添加多个异常类型,中间用逗号隔开,但是需要用括号包裹,变成一个元组
- 可以书写多个except
- 如果所有的异常类型都无法捕获到该异常, 或者我们需要捕获未知类型的异常,可以使用Exception
1 | # try: |
9、else 和 finally
- else: try中控制的代码没有出现异常,则执行该结构内的代码
1 | ''' |
- finally:无论出现什么情况都会执行finally里边的代码,哪怕程序崩溃
1 | ''' |
10、自定义异常抛出
- 自定义异常一定要继承自Exception
- 自定义异常可以使用raise抛出,可以进行捕获或者导致程序终止
- raise可以抛出系统异常,也可以抛出自定义异常
1 | # 自定义异常的逻辑 |
11、模块的导入
1 | import 模块名 |
1 | # Python中的模块就是可以将别人写好的,或者自己以前写好的功能直接导入新的文件或工程内,导入后可以直接调用 例如 : random time os |
12、自定义模块
模块名一定要遵循标识符的命名规则才能被导入
模块中书写的全局变量,函数,类可以盗取其他文件
导入模块时,会将模块中的所有文件执行一遍
为了保证测试代码在导入模块时不被执行,我们的测试代码需要写入
if __name__ == '__main__:'
1 | # 标识符的命名规则 |
13、模块查询顺序
- sys.path可以查询模块调用路径列表,越靠前的路径越优先查询
1 | # 可以使用sys.path查看模块的定位顺序,如果模块名相同,优先从最新的序列查找 |
- 开发中可以添加调用路径 sys.path.append(路径)
14、__all__
的使用方式
1 | # __all__可以控制模块使用功能from 模块名 import *所导入的功能列表 |
15、包的的导入
- 导入包
- import 包名.模块名
- from 包名 import 模块名
- 如果想要使用功能from 包名 import *
- 要在
__init__.py
文件中书写__all__
添加指定模块名才能导入
- 要在
1 | # 包:多个有关联的模块在一起,保存在同一个文件夹内,并且文件内有一个__init__.py为文件,这种文件夹就叫做包 |
16、学生管理系统面向对象版
- main.py
1 | # 主程序入口 |
- Student.py
1 | # 定义学员类,并且在创建学员对象的时候添加学员信息 |
- Student_manager.py
1 | # 方法: |