Python 学习
声明:因个人能力有限,本文仅是个人的学习记录笔记,有错误之处还望指出
输出函数 print
-
输出内容
- 数字
- 字符串(要加 引号)
- 含有运算符的表达式
-
输出地址(文件 \ 显示器)
# 显示器
print('hello world')
# 文件
# a+ : 如果文件不存在就创建文件,存在的话在文件内容后面追加
fp = open('D:/text.text','a+')
print('hello world',file=fp)
fp.close()
转义字符和原字符
+ 转义字符首字母 \ + 转义字符首字母 +转义字符首字母
- \b : 退一个格
- \r : 回车
- \t : 水平制表符
- \n : 换行
不希望字符串中的转义字符起作用(使用原字符),在字符前面加上 r\R 且最后一个字符不能是反斜杠
二进制与字符编码
8 b i t = 1 b y t e 1024 b y t e = 1 K B 1024 k b = 1 M B 8bit = 1byte 1024byte = 1KB 1024kb = 1MB 8bit=1byte1024byte=1KB1024kb=1MB
标识符和保留字
保留字:被赋予了特定的意义,不能被使用(False ,None,and,as,assert,…)
标识符:变量,函数,类,模块起的名字
- 字母数字下划线
- 不能以数字开头
- 严格区分大小写
-
变量的定义和使用
变量由三部分组成
1. 标识:表示对象所存储的内存地址,使用内置函数 id(obj) 来获取
2. 类型:表示的是对象的数据类型,使用内置函数 type(obj) 来获取
3. 值 : 表示对象锁存储的具体数据,使用 print(obj) 将值进行打印
变量中存储的是标识的值(内存地址) -
变量的多次赋值
多次赋值之后,变量会指向新的内存地址(标识)
Python 中常用的数据类型
常用的数据类型
- int(整数类型):正/负数,零
默认十进制
进制 | 基本数 | 表现形式 |
---|---|---|
十 | 0~9 | 118 |
二 | 0,1 | 0b1110110 |
八 | 0~7 | 0o166 |
十六 | 0~9 A~F | 0x76 |
- float:整数部分和小数部分组成
可以导入 decimal 模块解决计算不精确的问题
- bool :真\假 值
bool 值可以转化为整数 True \ False = 1 \ 0
- str
称为不可变的字符序列,可以用 ’ ’ 或 " " 或 ‘’’ ‘’’ 或 “”" “”" 来定义
单引号和双引号定义的字符串必须在一行,三引号可以分布在连续的多行
数据类型转换
当两个不同数据类型的时候,函数会报错
-
数据类型转换函数
函数名 作用 注意事项 例子 str() 将其他数据类型换成字 符串 也可用引号转换 str (12) ‘12’ int() 将其他数据类型换成整 数 文字类和小数类字符串,无 法转换 浮点数转化成整数,抹 零取整 int(“123”) int(9.8) float() 将其他数据类型函数 转成浮点数 文字类无法转换 整数转换成浮点数,末尾为0 float(‘9.9’) float(9)
python 中的注释
-
# 作为单行注释
-
‘’’ ‘’‘’ 作为多行注释
-
中文编码声明注释:写在文件开头加上中文声明注释,用于指定源码文件的编码格式
#coding:gbk
input 函数的使用
接收用户的输入,输入的类型为 s t r str str
print('===输入函数的使用====')
name = input('你叫什么名字:')
print('\n', name, type(name))
# 从键盘获取两个整数并且计算和
print('\n', '===求和计算===')
num1 = input('数值a:')
num2 = input('数值b:')
print(num1, '+', num2, '=', int(num1)+int(num2))
运算符
-
算术运算符
运算符 表示 例子 结果 + 加 1 + 1 1+1 1+1 2 2 2 - 减 2 − 1 2-1 2−1 1 1 1 * 乘 2*3 6 / 除 1/2 0.5 % 取余(一正一负要公式) 9%4 1 % 余数=被除数 -除数 * 商 9%-4 9-(-4)*(-3) -3 ** 幂运算 2**3 2^3=8 // 整除(一正一负向下取整) 11//2 5 // 整除(一正一负向下取整) 9//-4 -3 // 整除(一正一负向下取整) -9//4 -3 -
赋值运算符
- 执行顺序 : 从右往左
- 支持链式赋值 : a=b=c=10
- 支持参数赋值 : += -= /= %= //=
- 支持 系列解包赋值 : a,b,c = 20,30,40
-
比较运算符
- 对变量 / 表达式的结果进行大小/真假的比较,运算的结果是 bool 类型
- = 称为赋值运算符, == 称为比较运算符用于比较值, is 用于比较对象的标识, is not 标识标识不相等
-
布尔运算符
运算符 备注 and 同为True 才为True or 有True 就True not 相反 in 在里面 not in 不在里面 -
位运算符
运算符 说明 位与 & 对应数位都为 1 , 才为 1 位或 | 对应位都为 0 , 才为0 左移位 << 高位溢出舍弃,低位补 0(*2) 右移位 >> 低位溢出舍去 , 高位补 0(/2) -
运算符的优先级
算术运算 > 位运算 > 比较运算 > 布尔运算 > 赋值运算符
程序的组织结构
基本结构由顺序结构,选择结构,循环结构组成
-
顺序结构
没有选择和跳转的按先后顺序执行的结构
-
对象的布尔值
Python 中一切皆为对象,所有的对象都有一个布尔值,通过 内置函数 bool() 来获取
-
以下对象的布尔值为 False
- Fasle
- 数值 0
- None
- 空字符串
- 空列表
- 空元祖
- 空字典
- 空集合
-
单分支结构
-
中文语义 : 如果 … 就 …
-
语法结构 :
if 条件表达式 : 条件执行体
-
-
双分支结构
-
中文语义 : 如果 … 不满足 … 就 …
-
语法结构 :
if 条件表达式 : 条件执行体1 else : 条件执行体2
-
-
多分支结构
-
中文语义 :
- 是 90 分以上? 不是
- 是 80 分到90 分? 不是
- 是 70 分到 80 分? 不是
- 是 60 分到 70 分 ? 是
-
语法结构 :
if 条件表达式 : 条件执行体1 elif : 条件执行体2 elif : 条件执行体N else : 条件执行体 N+1
-
-
嵌套 if 的使用
-
语法结构 :
if 条件表达式1 : if 内层条件表达式: 内层条件执行体1 else : 内层条件执行体2 else : 条件执行体
-
-
条件表达式
条件表达式是 if … else 的简写
- 语法结构: x if 判断条件 else y
- 运算规则: 判断条件的布尔值为 True ,条件表达式返回 x,否者返回 y
-
pass 语句
pass 语句什么都不做, 只是应该占位符,用在语法需要的地方
range 函数的使用
- 用于生成一个整数序列
- 创建 range 对象的三种方式
- range(stop):创建一个[0,stop]之间的整数序列,步长为 1
- range(start,stop):创建一个[start,stop]之间的整数序列,步长为 1
- range(start,stop,step):创建一个[0,stop]之间的整数序列,步长为 step
- 返回值是一个迭代器的对象
- range 类型的优点: 不管 range 对象表示的整数序列多长,所有 range 对象占用的内存空间都是相相同,存储的时候仅需要存储 start , stop , step ,只有在用到 range 对象的时候才会计算序列中的相关元素
- in 和 not in 可以判断序列是否存在指定的整数
循环结构
反复的做同一件事情
- 循环的分类
- while
- for-in
while 循环
-
语法结构:
while 条件表达式: 条件执行体(循环体)
-
选择结构的 if 与循环结构的 while 区别
- if 是判断一次,条件为 True 执行一次
- while 是判断 N + 1 次,条件为 True 执行 N 次
for-in 循环
-
for-in 循环
- in 表达从(字符串,序列等)中依次qu’z取值,又称为遍历
- for-in 遍历的对象必须是可迭代对象
-
for-in 语法结构
for 自定义变量 in 可迭代对象: 循环体
-
循环体内不需要访问的自定义变量,可以将自定义变量替代为下划线
流程控制语句
- break
用于结束循环结构,通常与分支结构 if 一起使用 - continue
用于结束当前循环,进入下一次循环,通常与分支结构 if 一起使用
嵌套循环
循环结构中又嵌套了另外完整的循环结构,其中内层循环做为外层循环的循环体执行
列表 []
列表相当于 C 语言的数组,列表中存储的是列表对象的 id,列表对象存储的是列表元素的 id。
-
创建
- 使用中括号:lst=[‘jack’,‘ryan’]
- 调用内置函数 list():lst1=list([‘jack’,‘ryan’])
-
特点
- 列表元素按顺序有序排序
- 索引映射唯一一个数据
- 可以存储重复数据
- 任意类型混存
- 根据需要动态分配和回收内存
-
查询
-
获取列表指定元素索引(index())
- 如果存在 N 个相同的元素,只返回相同元素中的第一个元素的索引
- 如果查询的元素在列表中不存在,则会返回 ValueError
- 可以在指定的 start 和 stop 之间进行查找
-
获取列表中的单个元素
- 正向索引 0 ~ N-1
- 逆向索引 -N ~ -1
- 指定索引不存在,抛出 IndexError
-
获取列表中的多个元素
- 语法格式
列表名[start:stop:step]
- 切片操作
- 切片的结果:原列表片段的拷贝
- 切片的范围:[start,stop)
- step 默认为 1:[start:stop]
- step 为正数:[:stop:step] / [start::step] 切片的第一个元素/最后一个元素默认是列表的第一个/最后一个元素 (从 start 开始往后计算切片)
- step 为负数:[:stop:step] / [start::step] 切片的第一个元素/最后一个元素默认是列表的最后第一个/第一个一个元素 (从 start 开始往前计算切片)
-
-
列表元素的判断和遍历
- 判断(in / not in)
- 遍历(for 迭代变量 in 列表名 )
-
列表元素的增加操作
方法 操作描述 append() 在列表的末尾添加一个元素 extend() 在列表的末尾至少添加一个元素 insert() 在列表的任意位置添加一个元素 切片 在列表的任意位置添加至少一个元素 -
列表元素的删除操作
方法 操作描述 操作对象 remove() 1. 一次删除一个元素 2. 重复元素只删除第一个 3. 不存在抛出 ValueError 元 素值 pop() 1. 删除一个指定索引上单元素 2. 指定索引不存在则抛出 IndexError 3. 不指定索 引,删除列表中的最后一个元素 索引值 切片 在列表的任意位置添加一个元素 clear() 清除列表 列表元素 del 删除列表 列表 -
列表元素的修改操作
- 为指定索引的元素赋予一个新值
- 为指定的切片赋予一个新值
-
列表的排序操作
- sort():默认从小到大排序,指定 reverse = True 来进行降序排序(原列表操作)
- sorted():指定 reverse = True,进行降序排序,原列表不发生改变(新列表)
-
列表生成式
- 语法格式
[item for item in range(start,stop)] # 第一个 item 是用于标识元素值,可以自定义各个值之间的关系
字典
-
字典 {}
- Python 的数据结构,与列表用一样是一个可变序列(可增删改查)
- 以键值对的方式存储数据,字典是一个无序的序列
# 每个键值对之间通过逗号隔开 scores={'jack':100,'Ryan':200}
- 字典实现原理:根据部首或拼音查找对应的页码,python中的字典是根据 key 查找 value所在的位置
-
字典的创建
- 使用花括号 {}
- 使用内置函数 dict()
-
字典中元素的获取
- 使用 [] : 查找不存在则报错 keyError
- 使用 get():查找不存在返回 None 不报错,可以通过参数设置默认的 value,便于指定 value 不存在的时候返回
-
字典常用操作
- key 的判断
- in : 指定的 key 在字典中存在返回 True (‘jack’ in score)
- not in : 指定的 key 在字典中不存在返回 True (‘jack’ not in score)
- 字典元素的删除
del scores[‘张三’]
- 字典元素的新增
score[‘tom’]=100
- 清空字典元素
score.clear()
- key 的判断
-
获取字典视图的三个办法
- keys():获取字典中所有 key
- values():获取字典中所有 value
- intems():获取字典中所有 key,value 对
-
字典元素的遍历
for item in scores: print(item)
-
字典的特点
- 字典中所有的元素都是一个 key-value对,key 不允许重复,value 可以重复
- 字典中的元素是无序的
- 字典中的 key 必须是可变对象
- 字典也可以根据需要动态的伸缩
- 字典会浪费较大的内存,这是一种使用空间换时间的数据结构
-
字典生成式
-
内置函数 zip()
- 用于将可迭代对象作为参数,将对象中对应的元素打包成一个元组,然后返回这些元组组成的列表
item=['fruit','book','others'] price=[100,200,300] lst=zip(item,price) # 字典生成式 goods={item:price for item ,price in zip(item,price)}
-
元组
-
元组 ()
- Python 的内置数据结构,是一个不可变序列(故无法增删改)
-
可变序列和不可变序列
- 可变:列表、字典(可以增删改操作,且对象地址不发生改变)
- 不可变:元组、字符串(没有增删改操作)
-
元组的创建的方式
- 直接使用小括号(非空时小括号也可以省略)
t=(‘python’,100)
- 使用内置函数 tuple()
t=tuple((‘python’,100))
- 只包含一个元组的元素需要使用逗号和小括号
t=(10,)
- 直接使用小括号(非空时小括号也可以省略)
-
元组的不可变序列原因
-
在多任务环境下,同时操作对象时不需要加锁(尽量使用不可变序列)
-
元组中存储的是对象的引用(id)
- 如果元组中的对象本身不可对象,则不能再引用其他对象
- 如果元组中的对象是可变对象,则可变对象的引用不允许改变,但数据可以改变
t=(10,[20,30]0,100) print(t[0],type(t[0]),id(t0)) print(t[1],type(t[1]),id(t1)) print(t[2],type(t[2]),id(t2)) # 尝试将 t[1] 修改为 100 # t[1]=100 元组是不允许修改元素的 # 因为 t[1] 是列表,列表是可变序列,可以添加数据,且列表的内存地址不变 t[1].append(100) # 向列表中添加元素
-
-
元组的遍历
-
元组是可迭代对象,可以用 for-in 来遍历
d=(1,2,3,'hello','world') for item in d print(item)
-
集合
- 集合 {}
- Python 语言提供的内置数据结构
- 与 列表、字典一样都是属于可变类型的序列
- 集合是没有 value 的字典
- 集合元素不允许重复
- 集合元素无序
- 集合的创建方式
- 使用 {}
s={‘python’,‘hello’,100}
- 使用内置函数 set()
s=set(range(11))
- 空集合
s=set()
- 使用 {}
- 集合的相关操作
- 判断操作
in / not in
- 新增操作
add() 一次添中一个元素
update() 一次至少添中一个元素 - 删除操作
remove() 一次删除一个指定元素,如果指定元素不存在则抛出 KeyError
discard() 一次删除一个指定元素,如果指定的元素不存在你抛出异常
pop() 一次只删除一个任意的元素
clear() 清空集合
- 判断操作
- 集合间的关系(set_1 和 set_2)
- 是否相等
set_1 == set_2 / set_1 != set_2
- 一个集合是否是另一个集合的子集
set_1.issubset(set_2)
- 一个集合是否是另一个集合的超集
set_1.isuperset(set_2)
- 两个集合没有交集
set_1.isdisjoint(set_2)
- 是否相等
- 集合的数学操作
- 交集
set_1 & set_2
set_1.intersection(set_2) - 并集
set_1.union(s2)
set_1 | set_2 - 差集
set_1.difference(set_2)
set_1 - set_2 - 对称差集
set_1.symmetric_difference(set_2)
set_1 ^ set_2
- 交集
- 集合生成式
-
用于生成集合的公式
# 列表生成式 l=[item for item in range(1,11)] print(l) # 集合生成式 s=[item for item in range(1,11)] print(s)
-
字符串
-
字符串
字符串是 Python 中的基本数据类型,是一个不可变字符序列 -
字符串的驻留机制
仅保存一份相同且不可变字符串的方法,不同的值被存放在字符串的驻留池中,Python的驻留机制对相同的字符串只保留一份拷贝,后续创建相同的字符串时,不会开辟新的空间,而是把该字符串的地址赋给新创建的变量- 驻留机制的情况
- 字符串的长度为 0 或 1 时
- 符合标识符的字符串
- 字符串只在编译时候进行驻留,而非运行时
- [-5,256]之间的整数数字
- sys中的intern方法强制2 个字符串执行同一个对象
- 字符串驻留机制的优缺点
- 当需要值相同的字符串时候,可以直接从字符串池里拿出来使用,避免频繁的创建和销毁,提升效率与节约内存,因此拼接字符串和修改字符串是比较影响性能
- 在需要进行字符串拼接时候建议使用 str 类型的join 方法,而非 + , 因为 join() 方法是先计算出所有字符串的长度,然后再拷贝,只 new 因此对象,效率比 + 高
- 驻留机制的情况
-
字符串的查询操作方法
方法名称 作用 index() 查找字串 substr 第一次出现的位置,如果查找的字串不存在时,则抛出 ValueError rindex() 查找字串 substr 最后一次出现的位置,如果查找的字串不存在时,则抛出 ValueError find() 查找字串 substr 第一次出现的位置,如果查找的字串不存在时,则返回 -1 rfind() 查找字串 substr 最后一次出现的位置,如果查找的字串不存在时,则返回 -1 -
字符串的大小写转换操作
方法名称 作用 upper() 把字符串中的所有字符转换成大写字符 lower() 把字符串中的所有字符转换成小写字符 swapcase() 把字符串中的所有小写字符转换成大写字符,大写字符转换成小写字符(所有字符都改变) capitalize 把第一个字符转换为大写,其余字符转换为小写 title() 把每个单词的第一个字符转化为大写,把每个单词的剩余字符转换为小写 -
字符串内容对齐的方法
方法名称 作用 center() 居中对齐,参数1:宽度、参数2:填充符(可选,默认是空格)。如果设置宽度小于实际宽度则返回原字符串 ljust() 左对齐,参数1:宽度,参数2:填充符(可选,默认是空格)。如果设置宽度小于实际宽度则返回原字符串 rjust() 右对齐,参数1:宽度,参数2:填充符(可选,默认是空格)。如果设置宽度小于实际宽度则返回原字符串 zfill() 右对齐,左边用0填充,该方法只接收一个参数,用于指定字符串的宽度,如果指定宽度小于等于字符串的长度,则返回字符串本身 -
字符串的劈分操作
方法名称 作用 split() 1. 从字符串的左侧开始劈分,默认的劈分字符是空格字符串,返回值都是一个列表 2. 通过参数 sep 指定劈分字符串的劈分符 3. 通过参数 maxsplit 来指定劈分字符串时的最大劈分次数,在经过最大次的劈分后,剩余的字串会单独作为一部分 rsplit() 1. 从字符串的右侧开始劈分,默认的劈分字符是空格字符串,返回值都是一个列表 2. 通过参数 sep 指定劈分字符串的劈分符 3. 通过参数 maxsplit 来指定劈分字符串时的最大劈分次数,在经过最大次的劈分后,剩余的字串会单独作为一部分 -
字符串的判断方法
方法名称 说明 isidentifier() 判断字符串是否是合法字符 isspace() 判断字符串是否全部由空白字符组成(回车、换行、水平制表符) isalpha() 判断字符串是否全部由字母组成 isdecimal() 判断字符串是否全部由十进制的数字组成 isnumeric() 判断指定的字符串是否全部由数字组成 isalnum() 判断指定字符串是否全部由字母数字组成 -
字符串的其他操作
功能 方法名称 作用 字符串的替换 replace() 第一个参数指定被替换的字符串,第二个参数指定替换子串的字符串,该方法返回替换后得到的字符串,替换前的字符串不发生变化,调用该方法时可以通过第3个参数来指定最大替换次数 字符串的合并 join() 将列表或元组中的字符串合并成一个字符串 -
字符串的比较操作
- 运算符:
> >= <= < == !=
- 比较规则:
首先比较两个字符串中的第一个字符,如果相等则继续比较下一个字符,依次的比较下去,知道两个字符串中的字符不相等,其结果就是比较这两个字符串的比较结果,两个字符串的所有后续字符将不再被比较 - 比较原理:
比较的是其 ordinary value (原始值),调用其内置函数 ord 可以得到指定字符的 ordinary value 。与其内置函数ord 对应的是内置函数 chr,调用内置函数 chr 时指定 ordinary value 可以得到其对应的字符 - == 与 is 的区别:
- == 比较的是 value
- is 比较的是 id
- 运算符:
-
字符串的切片操作
- 字符串是不可变的类型
- 不具备增删改操作
- 切片操作将参数新的对象
- 字符串是不可变的类型
-
格式化字符串
- % 作为占位符
‘我叫 %s,今年%d岁了’%(name,age)
- {} 作为占位符
‘我的名字叫:{0},今年{1}岁了,我的真名叫:{0}’.format(name,age)
- f-string
f’我叫{name},今年{age}岁’
- % 作为占位符
-
字符串的编码转换
- 编码:将字符串转换为二进制数据(bytes)
- 解码:将bytes类型的数据转换成字符串类型
函数
-
函数的创建和调用
-
函数:执行特定功能的代码
-
函数的创建
def 函数名称 ([输入参数]): 函数体 [return xxx]
-
-
函数的参数传递
- 位置实参:根据形参对应的位置进行实参传递
- 关键字实参:根据形参进行实参传递
- 在函数调用过程中,进行参数的传递:
- 如果是不可变对象,在函数体的修改下不会影响实参的值, arg1的修改为 100,不会影响 n1 的值
- 如果是可变对象,在函数体的修改会影响实参的值, arg2的修改,append(10),会影响 n2 的值
-
函数的返回值
- 函数返回多个值时,结果为元组
- 如果函数没有返回值 (函数执行完毕,不需要给调用处提供数据) return 可省略不写
- 如果是一个返回值,则直接返回类型
-
函数的参数定义
-
函数定义时,给形参设置默认值,只有与默认值不符的时候才需要传递实参
-
个数可变的位置参数(只能是一个)
- 定义参数时,可能无法事先确定传递的位置实参个数的时候,使用可变的位置参数
- 使用 * 定义个数可变的位置形参
- 结果为一个元组
def fun(*args): print(args)
-
个数可变的关键字参数(只能是一个)
- 定义函数的时候,无法事先确定传递的关键字实参个数,使用可变的关键字形参
- 使用 ** 定义个数可变的关键字形参
- 结果为一个字典
def fun(**args): print(args)
-
既有关键字形参和位置形参时,要求位置形参放在关键字形参之前
-
-
函数参数的总结
参数类型 函数定义 函数的调用 备注 位置实参 √ 将序列中的每个元素都转换为位置实参 √ 使用 * 关键字实参 √ 将字典中的每个键值对都转换为关键字实参 √ 使用 ** 默认形参 √ 关键字形参 √ 使用 * 个数可变的位置形参 √ 使用 * 个数可变的关键字形参 √ 使用 ** -
变量的作用域
- 程序代码能够访问该变量的区域
- 更具变量的有效范围分为
- 局部变量:在函数内定义并使用的变量,只在函数内部有效,局部变量使用 global 声明,这一变量就会成全局变量
- 全局变量:函数体外的变量,可作用于函数内外
-
递归函数
- 一个函数的函数内调用了该函数本身
- 组成部分:递归调用+递归终止条件
- 递归的调用过程
- 每递归调用一次函数,都会在栈内分配一个栈帧
- 每执行完一次函数,都会释放相应的空间
- 优缺点
- 优点:思路、代码简单
- 缺点:占用内存多、效率低下
BUG
-
常见的 Bug 的类型
-
粗心导致的语法错误 SyntaxError
- 遗漏末尾的冒号,if 语句循环语句,else 子语句
- 缩进错误
- 把英文符号写成中文符号
- 字符串拼接的时候,将字符串和数字拼接在一起
- == 比较运算符 和 = 赋值运算符混用
- 没有定义变量(循环条件)
-
概念不清晰导致的问题
- 索引越界 IndexError
- append方法使用不熟练
-
思路不清晰导致的 Bug
- 使用 print 来进行排查
- 使用 # 暂时注释代码
-
用户操作错误导致的 Bug
- 采用 Python 的异常处理机制,在出现异常时捕获,然后内部"消化",让程序继续执行(支持多个 except)
try : 可能会出现异常的代码 except XXX(异常类型): 异常处理代码 # 例子 try : n1=int(input('输入一个数:')) n2=int(input('输入另外一个数:')) result = a/b print('结果为:',result) except ZeroDivisionError: print("除数不允许为 0") print('程序结束')
-
-
异常处理机制
- try … except … else 结构
如果 try 块中没有抛出异常,则执行 else 块,如果 try 抛出异常,则执行 except 块
# 例子 try : n1=int(input('输入一个数:')) n2=int(input('输入另外一个数:')) result = a/b except BaseException as e: # 异常取别名,进行输出 print("出错") print(e) else: print('结果为:',result) print('程序结束')
-
try … except … else … finally结构
finally 块无论是否发生异常都会被执行,能常用俩释放 try 块中申请的资源# 例子 try : n1=int(input('输入一个数:')) n2=int(input('输入另外一个数:')) result = a/b except BaseException as e: # 异常取别名,进行输出 print("出错") print(e) else: print('结果为:',result) finally: print('无论是否发生异常,总会被执行的代码') print('程序结束')
- try … except … else 结构
-
常见的异常类型
异常类型 描述 ZeroDivisionError 除(或取模)零(所有数据类型) KeyError 映射中没有这个键 SyntaxError Python 语法错误 ValueError 传入无效的参数 -
tarceback 模块的使用
提供 tracekace 模块来进行打印异常import traceback try: print('---------') print('10/0') except: traceback.print_exc()
编程的两大思想
-
两大编程思想
面向过程 面向对象 区别 事物比较简单,可以用线性思维解决 事物比较复杂,使用简单的线性思维无法解决 共同点 都是解决问题的一种思维方式 都是解决问题的一种思维方式 -
类与对象
- 类:多个类似事物组成的群体统称
- 对象:100,90,0 都是 int 类下包含相似的不同个例,这个个例称为实例或对象
-
类的创建
class Student: # Student 是类的名称 # 直接写在类里面的变量,称为类属性 native_pace = 'HongKong' def __init__(self, name, age): # self.name 称为实体属性,进行了一个赋值操作,将局部变量的name值赋给实体属性 self.name = name self.age = age # 实例方法 def eat(self): print('i like eat watermelon') # 静态方法 @staticmethod def method(): print('i have used staticmethod ,so it is static method') # 类方法 @classmethod def cm(cls): print('i have used staticmethod ,so it is class method ')
-
对象的创建(类的实例化)
-
语法:
实例名 = 类名() # 例子 stu=Studnt('jack',20) # 实例属性 print(stu.name) # 实例属性 print(stu.age) # 实例方法 stu.info()
-
意义:有了实例,可以调用类中的内容(相当于 C 中的结构体对象)
-
-
类属性,类方法,静态方法
-
类属性:类中方法外的变量称为类属性,被该类的所有对象所共享
-
类方法:使用 @classmethod 修饰的方法,使用类名直接访问的方法
-
静态方法:使用 @staticmethod 修饰的方法,使用类名直接访问的方法
实例名 = 类名() # 例子 stu=Studnt('jack',20) # 访问类属性 print(Student,native_place) # 调用类方法 Student.cm() # 调用静态方法 Student.sm()
-
-
动态绑定属性和方法
Python是动态语言,在创建对象之后,可以动态的绑定属性和方法def show(): print('我是函数,在绑定之后变为方法') stu=Student('Jack',20) # 动态绑定性别 stu.gender='Male' #动态绑定方法 stu.show=show # 调用方法 stu.show()
面向对象
-
面向对象的三大特征
- 封装:提高出现的安全性
- 将数据(属性)和行为(方法)包装到类对象中。在类对象的外部调用方法。这样子就无序关心方法内部的具体实现细节,进而隔离了复杂度
- 在 Python 中没有专门修饰符用于属性私有,如果该属性不希望在类对象访问,前面使用两个’_’
- 继承:提高代码的复用性
- 多态:提高出现的可扩展性和可维护性
- 封装:提高出现的安全性
-
封装
class Student: def __init__(self, age): self.set_age(age) def get_age(self): # 仅限在类中使用(加了两个_) return self.__age def set_age(self, age): if 0 <= age <= 120: self.__age = age else: self.__age = 18 Stu1 = Student(150) Stu2 = Student(15) print(Stu1.get_age()) print(Stu2.get_age())
- 显示私有的属性
通过dir(实例名称)来查看可用的方法
print(stu.Student.__age)
-
继承
-
语法格式
class 子类类名(父类1,父类2...): pass
-
代码实现
Student和Teacher 继承 Person
class 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, teach_of_year): super().__init__(name, age) self.teach_of_year = teach_of_year stu = Student('Jack', 100, 1001) teacher = Teacher('Ryan', 42, 10) stu.info() teacher.info()
- 如果一个类没有继承任何类,则默认继承 object
- Python 支持多继承
- 定义子类时,必须在其构造函数中调用父类的构造函数
-
-
方法重写
- 如果子类对继承自父类的某个属性/方法不满意,可以在子类中对其(方法体)进行重新编写
- 子类重写之后的方法中可以通过 super().xxx() 调用父类中被重写的方法
class 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 def info(self): super().info() print('学号:', self.stu_no) class Teacher(Person): def __init__(self, name, age, teach_of_year): super().__init__(name, age) self.teach_of_year = teach_of_year def info(self): super().info() print('教龄:', self.teach_of_year) stu = Student('Jack', 100, 1001) teacher = Teacher('Ryan', 42, 10) print('====方法重写=====') stu.info() teacher.info()
-
object 类
- object 类是所有类的父亲,因此所有类都有 object 类的属性和方法
- 内置 dir() 可以查看所有指定对象所有属性
- Object 有一个 _str_() 方法,用于返回一个对于"对象的描述",对应内置函数 str() 经常用于 print() 方法,帮我们查看对象的学习,所以我们经常会对 _str_()进行重写
class Pupil: def __init__(self, name, age): self.name = name self.age = age def __str__(self): return '我叫:{0},今年{1}岁'.format(self.name, self.age) stu = Pupil('Jack', 20) print(dir(stu)) print(stu) # 默认调用 __str__() 方法 print(type(stu))
-
多态
多态:具有多种形态;即便不知道一个变量所引用的对象是什么类型,仍然可以通过这个对象调用的方法,在运行过程中更具变量所引用对象的类型,动态的决定调用那个对象中的方法class Animal(object): def eat(self): print('动物会吃') class Dog(Animal): def eat(self): print('狗吃骨头...') class Cat(Animal): def eat(self): print('猫吃鱼...') class Person: def eat(self): print('人吃五谷杂粮...') def fun(obj): obj.eat() # 开始调用 fun(Cat()) fun(Dog()) fun(Person())
- 静态语言和动态语言关于多态的区别
- 静态语言实现多态的三个必要条件
- 继承
- 方法重写
- 父类引用指向子类对象
- 动态语言的多态崇尚"鸭子类型",在鸭子类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为
- 静态语言实现多态的三个必要条件
- 静态语言和动态语言关于多态的区别
-
特殊的方法和属性
名称 描述 特殊属性 _dict_ 获得类对象或实例对象所绑定的所有属性和方法的字典 特殊方法 _len()_ 通过重写 _len()_ 方法,让内置函数 len() 的参数可以是自定义类型 特殊方法 _add()_ 通过重写 _add()_ 方法,可使用自定义对象具有"+"功能 特殊方法 _new()_ 用于创建对象 特殊方法 _init()_ 对创建的对象进行初始化 -
类的浅拷贝和深拷贝
- 变量的赋值操作
只是形成两个变量,实际上还是指向同一个对象 - 浅拷贝
Python 拷贝一般都是浅拷贝,拷贝时,对象包含的子对象内容不拷贝,因此,源对象鱼拷贝对象会引用同一个子对象 - 深拷贝
使用 copy 模块的 deepcopy 函数,递归拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同
- 变量的赋值操作
模块
-
模块
- 一个模块中可以包含多个函数、类、语句
- Python中以 .py 结尾的文件就是模块
-
模块的导入
- 创建模块:新建一个 .py 文件尽量不使用与 python 自带的标准模块相同
- 导入模块
与 C 语言的库函数类似,使用库函数的语句都要 include
import 模块名称 [as 别名] # 导入模块所有 from 模块名称 import 函数/变量/类 # 导入模块的部分 # 使用导入整个模块 函数/变量/类 # 使用导入部分函数 模块名称.函数/变量/类 # 例子 modle是自定义模块 ############################################# # 第一种种导入方式 import module print(module.div(2, 1)) print(module.fun(2, 1)) ############################################# # 第二种导入方式 from module import fun from module import div # div 使用moudle模块的 div 函数 print(fun(1, 2)) print(div(1, 2))
-
以主持下形式运行
-
在每个模块的定义中都包括一个记录模块名称的变量__name__,以确定他们在那个模块中执行。如果一个模块不是被导入到其他程序中执行,那么它可能子啊接收器的顶级模块中执行。顶级模块的__name__变量的值为__main__
# 只有当点击运行module时候才会运行并不会因为引用该模块就全部运行 if __name__ == "__main__": print('==================') print('main是顶级模块')
-
-
Python 中的包
- 包是一个分层次的目录结构,它将一组功能相近的模块组织在一起
- 包和目录的区别
- 包含__init__.py 文件的目录称为包
- 目录里通常不包含__init__.py
-
Python常用的内置模块
模块名 描述 sys 与python解释器及其环境操作相关的标准库 time 提供时间相关的各种函数标准库 os 提高了访问操作系统服务功能的标准库 calender 提提供与日期相关的各种函数标准库 urllib 用于读取来自网上的数据标准库 json 用于使用 JSON 序列化和反序列化对象 re 用于子啊字符串中执行正则在表达式匹配和替换 math 提供标准算术运算函数的标准库 decimal 用于精确控制运算的精度,有效位数和四舍五入操作的十进制运算 logging 提供了灵活的记录事件、错误、警告和调试信息等日志信息功能 -
第三方模块的安装和使用
- 安装
pip install 模块名称
- 使用
import 模块名称
- 安装
操作文件
-
编码格式
- Python的解释器使用的是 Unicode(内存)
- .py 文件在磁盘上使用 UTF-8 存储(外存)
- UTF-8:变长编码,1-4个字节表示一个字符,英文一个字节,汉字三个字节
- GBK:英文1字节,汉字两字节
-
文件读写原理
- 读写流程
- 打开\新建文件
- 读写文件
- 关闭资源
- 文件读写操作
- 内置函数 open() 创建文件对象
- 语法规则
file=open()
- 读写流程
-
常用的文件打开模式
-
文件类型
- 文本文件:存储的是普通的"字符"文本,默认为unicode字符集,可以使用记事本程序打开
- 二进制文件:把数据内容用"字节"进行存储,无法通过记事本打开,必须使用专用软件才可以打开(mp3文件,jpg图片,doc文档)
打开模式 描述 r 只读模式打开 w 只写模式打开,文件不存在则创建,存在则覆盖原有内容 a 追加模式打开文件,不存在则创建,存在则在文件末尾追加 b 二进制方式打开文件,不能单独使用,要和其他模式共用,如:rb,wb + 以读写方式打开文件,不能单独使用,需要与其他模式共用,如:a+
-
-
文件对象的常用方法
方法名 描述 read([size]) 从文件中读取size个字节或字符的内容返回,若省略[size],则读取到文件末尾,则一次读取文件所有内容 readline() 从文本文件中读取一行内容,'\n’为换行符,返回空则声明读到最后一行 readlines() 把文本文件中的每一行都作为独立的字符串对象,并将这些字符串放入列表返回 write(str) 将str写入文件,并返回写入的字节数 writelines(s_list) 将字符串列表s_list 写入文本文件,不添加换行符 seek(offset,whence) 将文件指针移动到新的位置,offset:表示相对于whence的位置:whence:0(文件开头)1(当前位置)2(文件结尾,此时移动的位置是负数) tell() 返回文件指针当前位置 flush() 将缓冲区的内容写入文件 close() 将缓冲区的内容写入文件,同时关闭文件,释放文件对象相关资源 -
with语句
with语句可以自动管理上下文资源,不论什么原因体跳出with块,都能确保文件正确的关闭,以此达到释放资源的目的 -
目录操作
os模块是 Python 内置的与操作系统功能和文件系统相关的模块,该模块中执行的语句通常和操作系统有关,在不同的操作系统上运行可能得到结果不同-
os模块与os.path模块用于对目录\文件进行操作
-
os 模块操作目录的相关函数
函数 说明 getcwd() 获取当前工作目录 mkdir(path[,mode]) 创建目录 makedirs(path1/path2/…[mode]) 创建多级目录 listdir(path) 返回指定目录下的文件和目录信息 rmdir(path) 删除目录 removedirs(path1/path2/…) 删除多级目录 chdir(path) 将path设置为当前工作目录 -
os.path模块操作目录相关函数
函数 说明 abspath(path) 获取文件或目录的绝对路径 exists(path) 判断文件或目录是否存在,存在:True,不存在:False join(path,name) 将目录与目录或者文件名拼接在一起 splitext() 分离文件名和拓展名 basename(path) 从一个路径中提取文件路径,不包括文件名 isdir(path) 判断是否为路径 walk 可以遍历指定目录下的所有文件
-