Python
—— B站 Python 课程自学笔记 【B站网课】
一、python简介
1、简介
python是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。
Python是解释型语言︰这意味着开发过程中没有了编译这个环节。类似于PHP和Perl语言。
Python是交互式语言︰这意味着,您可以在一个Python提示符
>>>
后直接执行代码。Python是面向对象语言:这意味着Python支持面向对象的风格或代码封装在对象的编程技术。
Python是初学者的语言:Python对初级程序员而言,是一种伟大的语言,它支持广泛的应用程序开发,从简单的文字处理到wwW浏览器再到游戏。
2、Python发展历史
Python是由Guido van Rossum在八十年代末和九十年代初,在荷兰国家数学和计算机科学研究所设计出来的。
Python本身也是由诸多其他语言发展而来的,这包括ABC、Modula-3、C、C++、Algol-68、SmalTalk、Unix shell和其他的脚本语言等等。
像Perl语言一样,Python源代码同样遵循GPL(GNU General Public License)协议。
现在Python是由一个核心开发团队在维护,Guido van Rossum仍然占据着至关重要的作用,指导其进展。Python 2.7被确定为最后一个Python 2.x版本,它除了支持 Python 2.x语法外,还支持部分Python 3.1语法。
3、python解释器
python3.8.0百度网盘 提取码:kksk
安装流程:选择自定义安装(Customize installation),之后的有选项的全选,路径记得修改即可
安装好后,在命令行窗口输入
1 |
|
如下显示即安装成功
安装后的说明
4、Pycharm设置
(2)代码模板设置
设置效果:
5、pip工具
Python自带,支持Python扩展库的安装,升级和卸载等操作
pip命令示例 | 说明 |
---|---|
pip --version | 显示版本和路径 |
pip --help | 获取帮助 |
pip list | 列出已安装的模块及其版本号 |
pip install SomePackage[==version] | 在线安装SomePackage模块的指定版本 |
pip install SomePackage. whl | 通过whl文件离线安装扩展库 |
pip install Package1, package2 ··· | 依此(在线)安装Package1,Package2… |
pip install -U SomePackage | 升级SomePackage模块 |
pip uninstall SomePackage | 卸载SomePackage模块 |
pip show SomePackage | 显示已安装的包的信息 |
常见pip镜像源(国内源)
-
华中理工大学:http://pypi.hustunique.com/
-
山东理工大学:http://pypi.sdutlinux.org/
使用:
1 |
|
或者全局设置:
1 |
|
注意:如果存在多个python版本,则pip后面跟版本号,就可以指定使用哪一个,例如pip3.8 ...
、pip3.10 ...
二、基础知识
1、转义字符
字符 | 效果 |
---|---|
\n | 换行 |
\b | 一个退格 |
\t | tab |
\\ | \ |
\" | " |
原字符:不希望字符串中的 转义字符 起作用
使用:就是在字符串前加 r 或 R
效果:
1 |
|
输出:
1 |
|
2、保留字
1 |
|
输出结果:
1 |
|
3、标识符
变量、函数、类、模块和其它对象的起的名字就叫标识符
规则:
- 字母、数字、下划线_
- 不能以数字开头
- 不能是保留字
- ·严格区分大小写
4、变量
变量是内存中一个带标签的盒子
变量由三部分组成:
- 标识: 表示对象所存储的内存地址,使用内置函数 id(obj) 来获取
- 类型: 表示的是对象的数据类型,使用内置函数 type(obj) 来获取
- 值: 表示对象所存储的具体数据,使用print(obj)可以将值进行打印输出
1 |
|
在多次赋值后,变量名会指向新的空间
1 |
|
5、数据类型
(1)整数类型
1 |
|
输出
1 |
|
(2)浮点类型
- 使用浮点数进行计算时,可能会出现小数点位数不精确的情况(因为计算机的二进制存储)
1 |
|
- 解决方案:
导入模块decimal
1 |
|
(3)布尔类型
可以转化为整数:True = 1; False = 0.
1 |
|
(4)字符串类型
- 字符串又被称为不可变的字符序列
- 可以使用单引号’ ‘、双引号" "、三引号’‘’ ‘’'或"“” “”"来定义
- 单引号和双引号定义的字符串必须在一行
- 三引号定义的字符串可以分布在连续的多行
1 |
|
输出:
1 |
|
6、数据类型转换
(1)str()
将其他类型转化成字符串类型;
(2)int()
将其他类型转化成int类型;(抹零取整)
文字类'123'
和小数'12.3'
串(是字符串,但是他显示的是一个浮点数)无法转换;
(3)float()
将其他类型转化成float类型;
文字类无法转;
7、注释
1 |
|
效果
8、运算符
(1)算术运算符
运算符 | 表示 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
% | 取余 |
** | 幂运算 |
// | 整数(一正一负,向下取整)print(11//2) # 输出为 5 |
(2)赋值运算符
-
支持链式赋值: a = b = c = 20
-
支持参数赋值:+=、-=、*=、/=、//=、%=
-
支持系列解包赋值:a, b, c = 20, 30, 40
1
2
3
4# 交换两个变量的值
a = 10
b = 20
a, b = b, a # a = 20, b = 10
(3)比较运算符
结果为bool类型
比较对象的标识用 is、 is not
1 |
|
(4)布尔运算符
and、or、not、in、not in
1 |
|
输出为:
1 |
|
(5)位运算符
(6)运算符优先级
9、对象的布尔值
-
Python —切皆对象 ,所有对象都有一个布尔值。
-
获取对象的布尔值,使用内置函数bool()
-
以下对象的布尔值为False(其他均为True)
-
False
-
数值0
-
None
-
空字符串
-
空列表 [] 、list()
-
空元组 () 、tuple()
-
空字典 {} 、dict()
-
空集合 set()
-
1 |
|
10、pass语句
语句什么都不做,只是一个占位符,用在语法上需要语句的地方
什么时候使用:先搭建语法结构,还没想好代码怎么写的时候
1 |
|
11、内置函数
可以使用下列语句查看所有内置函数
1 |
|
可以使用help(函数名)
查看某个函数的用法
(1)print()
1 |
|
参数 | 描述 |
---|---|
objects | 对象,表示可以一次输出多个对象。输出多个对象时,需要用 , 分隔 |
sep | 用来间隔多个对象,默认值是一个空格 |
end | 用来设定以什么结尾。默认值是换行符 \n,我们可以换成其他字符串 |
file | 要写入的文件对象 |
flush | 输出是否被缓存通常决定于 file,但如果 flush 关键字参数为 True,流会被强制刷新 |
1 |
|
问题:在运行Python文件时出现警告:PEP 8: W292 no newline at end of file
解决办法:在文件末尾加换行符(按回车即可)
(2)input()
变量 = input([提示语])
1 |
|
(3)range()
- 用于生成一个整数序列
-
返回值是一个迭代器对象
-
range类型的优点:不管range对象表示的整数序列有多长,所有range对象占用的内存空间都是相同的, 因为仅仅需要存储start,stop和step,只有当用到range对象时,才会去计算序列中的相关元素
-
in与not in判断整数序列中是否存在(不存在)指定的整数
-
三种创建方式:
1
2
3
4
5
6
7
8
9
10
11
12""" 1、只有一个参数 """
r = range(10) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 默认从 0 开始,默认相差1(步长)
print(r) # range(0, 10)
print(list(r)) # 用于查看 range 对象中的整数序列
""" 2、两个参数 """
r = range(1, 10) # range(start, stop, 默认相差1(步长))
print(list(r)) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
""" 3、三个参数 """
r = range(1, 10, 2) # range(start, stop, step)
print(list(r)) # [1, 3, 5, 7, 9]
(4)eval()待续
12、不可变序列与可变序列
-
不变可变序列:字符串、元组
不变可变序列没有增、删,改的操作
-
可变序列:列表、字典
可变序列可以对序列执行增、删、改操作,对象地址不发生更改
1 |
|
13、变量的作用域
- 程序代码能访问该变量的区域
- 根据变量的有效范围可分为
- 局部变量:
在函数内定义并使用的变量,只在函数内部有效 - 全局变量:
函数体外定义的变量,可作用于函数内外
- 局部变量:
局部变量使用global声明,这个变量就会就成全局变量
1 |
|
14、编码格式
常见的字符编码格式
- Python的解释器使用的是Unicode(内存)
- py文件在磁盘上使用UTF-8存储(外存)
指定文件的编码格式,utf-8是默认的
1 |
|
15、编程规范
\
续行符
三、程序的组织结构
1、顺序结构
由上往下顺序执行
2、分支结构
(1)单分支结构
一个缩进表示层次结构
1 |
|
(2)双分支结构
1 |
|
(3)多分支结构
1 |
|
(4)嵌套使用if
1 |
|
(5)条件表达式
1 |
|
3、循环结构
(1)while
1 |
|
(2)for_in
1 |
|
举例
如果不需要用到自定义变量,可写为’_’
1 |
|
输出:
1 |
|
(3)break语句、continue
-
break 用于结束循环;
-
continue 用于结束当前循环,进入下一循环。
(4)else语句和while、for_in搭配使用
- 控制本层循环
-
循环结束执行else
-
break跳出循环后不执行else
1 |
|
举例:
1 |
|
输出
1 |
|
四、列表、字典、元组、集合
1、列表
变量可以存储一个元素,而列表是一个“大容器”可以存储N多个元素,程序可以方便地对这些数据进行整体操作
(1)列表创建的方式
1 |
|
(2)列表的特点
-
列表元素按顺序有序排序
-
是一个可变序列
-
索引映射唯一个数据
-
列表可以存储重复数据
-
任意数据类型混存
-
根据需要动态分配和回收内存
(3)内存
1 |
|
输出结果
1 |
|
(4)获取、切片
-
获取列表指定元素的索引 index()
-
如查列表中存在N个相同元素,只返回相同元素中的第一个元素的索引
-
如果查询的元素在列表中不存在,则会抛出ValueError
-
还可以在指定的start和stop之间进行查找
-
index(‘目标’, start, end) # start~end-1 指定范围
1
2
3
4lst = ['hello', 'world', 98]
print(lst.index('hello')) # 0
print(lst.index('python')) # ValueError: 'python' is not in list
print(lst.index('hello',1,3)) # ValueError: 'hello' is not in list
-
-
根据索引获取元素
-
正向索引从 0 到 N - 1
-
逆向索引从 -N 到 -1
-
指定索引不存,抛出 indexError
1
2
3
4lst = ['hello', 'world', 98]
print(lst[0]) # hello
print(lst[-1]) # 98
print(lst[3]) # IndexError: list index out of range
-
-
切片操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14lst = [1, 2, 3, 4, 5, 6, 7, 8]
print('原列表', id(lst)) # 2016570503552
print('新列表', id(lst[1:6:1])) # 2016570470144
# 默认步长为 1
print(lst[1:6]) # [2, 3, 4, 5, 6]
# 默认start
print(lst[:6:2]) # [1, 3, 5]
# 默认stop
print(lst[1::2]) # [2, 4, 6, 8]
""" step为负数 """
print(lst[::-1]) # [8, 7, 6, 5, 4, 3, 2, 1]
print(lst[7::-2]) # [8, 6, 4, 2]
print(lst[6:0:-2]) # [7, 5, 3]
(5)查询列表、遍历
-
判断指定元素是否在列表中
元素 in 列表名
元素 not in 列表名
-
列表元素的遍历
1
2for 迭代对象 in 列表名:
操作1
2
3
4
5
6
7
8
9
10# 示例:
lst = [1, 2, 3, 4, 5, 6, 7, 8]
print(1 in lst) # True
print(10 in lst) # False
print(1 not in lst) # False
print(10 not in lst) # True
# 循环遍历
for item in lst:
print(item)
(6)添加
方法 | 描述 |
---|---|
append() | 在列表末尾添加一个元素 |
extend() | 在列表末尾添加至少一个元素 |
insert() | 在列表任意指定位置添加一个元素 |
切片 | 在列表任意指定位置添加至少一个元素 |
1 |
|
(7)删除
方法 | 描述 |
---|---|
remove() | 一次删除一个元素; 重复元素只删除第一个; 元素不存在抛出ValueError; |
pop() | 删除一个指定索引位置上的元素; 指定索引不存在抛出IndexError; 不指定索引,删除列表最后一个元素; |
切片 | 一次至少删除一个元素 |
clear() | 清空列表 |
del | 删除列表 |
1 |
|
(8)修改
- 为指定索引的元素赋予一个新值
- 为指定的切片赋予一个新值
1 |
|
(9)排序和列表生成式
排序
-
调用 sort() 方法,列有中的所有元素默认按照从小到大的顺序进行排序,可以指定reverse=True,进行降序排序
-
调用内置函数 sorted() ,可以指定reverse=True,进行降序排序,原列表不发生改变,产生新的列表对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17lst1 = [20, 40, 10, 98, 54]
print('排序前', lst1, id(lst1)) # 输出为 [20, 40, 10, 98, 54] 1776600150400
# 开始排序,调用列表对象的 sort 方法
lst1.sort()
print('排序后', lst1, id(lst1)) # 输出为 [10, 20, 40, 54, 98] 1776600150400
# 使用参数 reverse = True 降序, 默认为False
lst1.sort(reverse=True)
print(lst1) # 输出为 [98, 54, 40, 20, 10]
# ============================================================================
lst2 = [20, 40, 10, 98, 54]
new_lst2 = sorted(lst2)
print(lst2, id(lst2)) # 输出为 [20, 40, 10, 98, 54] 2450901070336
print(new_lst2, id(new_lst2)) # 输出为 [10, 20, 40, 54, 98] 2450901022144
# 指定关键字参数,降序
desc_lst2 = sorted(lst2, reverse=True)
print(desc_lst2) # 输出为 [98, 54, 40, 20, 10]
列表生成式
生成列表的公式
语法格式:
ps:“表示列表元素的表达式"中通常包含自定义变量
1 |
|
查看扩展内容
列表生成式的基本语法格式如下:
1 |
|
其中:
expression
是对item
的操作或表达式,用于生成新的元素。item
是迭代的元素。iterable
是可迭代对象,如列表、元组、字符串等。condition
是一个可选的条件,用于过滤元素。只有满足条件的元素才会被包含在新列表中。
可以根据需要省略 if condition
部分,只保留 expression for item in iterable
。
以下是一些示例:
- 生成一个包含 0 到 9 的平方的列表:
1 |
|
- 生成一个包含 0 到 9 的平方的列表,但只保留偶数:
1 |
|
- 将列表中的字符串转换为大写:
1 |
|
- 使用
if-else
语句生成一个包含奇数和偶数的列表,但奇数变为字符串形式:
1 |
|
这些示例演示了列表生成式的基本用法,你可以根据需要对其进行扩展和调整。
对最后一个例子进行解释:
这个列表生成式的语法结构是:
1 |
|
在这个例子中:
expression_if_true
是在满足条件x % 2 != 0
时对x
进行的操作,即将奇数转换为字符串形式。condition
是判断是否应该执行expression_if_true
的条件。expression_if_false
是在条件不满足时对x
进行的操作,即保持原值。item
是迭代的元素,这里是x
。iterable
是可迭代对象,这里是numbers
。
因此,这个列表生成式的作用是遍历 numbers
中的每个元素 x
,如果 x
是奇数(满足条件 x % 2 != 0
),则将其转换为字符串形式;如果 x
是偶数,则保持原值。生成的列表就是经过这样处理后的结果。
这是一个在列表生成式中使用 if-else
语句的示例。
2、字典
(1)什么是字典
- Python内置的数据结构之一,与列表一样是一个可变序列
- 以键值对的方式存储数据,字典是一个无序的序列
(2)实现原理
字典的实现原理与查字典类似,查字典是先根据部首或拼音查找应的页码,Python中的字典是根据key查找value所在的位置
字典示意图:
(3)创建
-
最常用:使用{}
scores = {'张三': 100, '李四': 98, '王五': 45}
-
使用内置函数dict()
scores = dict(张三='100', 李四='98', 王五='45')
1
2
3
4
5
6
7
8
9
10
11
12""" 1、使用{}创建字典 """
scores = {'张三': 100, '李四': 98, '王五': 45}
print(scores) # 输出为 {'张三': 100, '李四': 98, '王五': 45}
print(type(scores)) # 输出为 <class 'dict'>
""" 2、dict() """
scores = dict(张三='100', 李四='98', 王五='45')
print(scores) # 输出为 {'张三': '100', '李四': '98', '王五': '45'}
""" 空字典 """
scores = {}
print(scores) # 输出为 {}
(4)获取
-
[]
scores['张三']
-
get()
scores.get('张三')
-
区别
-
如果字典中不存在指定的key,抛出keyError异常
-
get()方法取值,如果字典中不存在指定的key,并不会抛出KeyErre
None,可以通过参数设置默认的value,以便指定的key不存在时返回get(key[, 默认值])
1
2
3
4
5scores = {'张三': 100, '李四': 98, '王五': 45}
# print(scores['ggw']) # 输出为 KeyError: 'ggw'
print(scores.get('ggw')) # 输出为 None
print(scores.get('ggw', '不造啊')) # 输出为 不造啊
print(scores.get('ggw', 404)) # 输出为 404
-
(5)增删改查
- 判断:in \ not in (key)
- 删除:del scores[‘张三’]
- 新增:scores[‘ggw’] = 99
- 修改:scores[‘ggw’] = 100
1 |
|
(6)常用方法
方法 | 描述 |
---|---|
keys() | 获取字典中所有的key |
values() | 获取字典中所有的value |
items() | 获取字典中所有的key, value对 |
1 |
|
(7)遍历
1 |
|
(8)特点
- 字典中的所有元素都是一个key-value对, key不允许重复, value可以重复
- 字典中的元素是无序的
- 字典中的key必须是不可变对象,字典也可以根据需要动态地伸缩
- 字典会浪费较大的内存,是一种使用空间换时间的数据结构
(9)字典生成式
内置函数zip()
用于将可迭代的对象作为参数,将对象中对应的元素打包成一个元组,然后返回由这些元组组成的列表
1 |
|
3、元组
Python内置的数据结构之一,是一个不可变序列
(1)创建
- 小括号()
- 使用内置函数 tuple()
- 只包含一个元组的元素需要使用逗号和小括号
1 |
|
(2)为什么元组要设计成不可变的序列
-
在多任务环境下,同时操作对象时不需要加锁
-
因此,在程序中尽量使用不可变序列
-
注意事项: 元组中存储的是对象的引用
- 如果元组中对象本身不可对象,则不能再引用其它对象
- 如果元组中的对象是可变对象,则可变对象的引用不允许改变,但数据可以改变
1 |
|
(3)获取、遍历
1 |
|
4、集合
- Python语言提供的内置数据结构
- 与列表、字典―样都属于可变类型的序列
- 集合是没有value的字典
(1)创建
-
花括号{}
s = {1, 2, 4, 5, 5, 7, 7}
-
使用内置函数set()
s = set(range(6))
1 |
|
(2)增删改查
-
集合元素的判断操作
in或not in
-
集合元素的新增操作
方法 描述 add() 一次添加一个元素 update() 至少添加一个元素 -
集合元素的删除操作
方法 描述 remove() 一次删除一个指定元素,如果指定的元素不存在抛出KeyError discard() 一次删除一个指定元素,如果指定的元素不存在不抛出异常 pop() 一次只删除一个任意元素 clear() 清空集合
1 |
|
(3)集合间的关系
-
两个集合是否相等
- 可以使用运算符==或!=进行判断
-
一个集合是否是另一个集合的子集
-
可以调用方法 issubset() 进行判断
-
B是A的子集
-
-
一个集合是否是另一个集合的超集
-
可以调用方法 issuperset() 进行判断·
-
A是B的超集
-
-
两个集合是否没有交集
- 可以调用方法 isdisjoint() 进行判断,有交集为False
1 |
|
(4)集合间的数学操作
-
交集:
s1.intersection(s2)
或者s1 & s2
-
并集:
s1.union(s2)
或者s1 | s2
-
差集:
s1.difference(s2)
或者s1 - s2
-
对称差集:
s1.symmetric_difference(s2)
或者s1 ^ s2
ps:原集合都没有变化
1 |
|
(5)集合生成式
1 |
|
5、总结
五、字符串
在Python中字符串是基本数据类型,是一个不可变的字符序列
1、字符串的驻留机制
仅保存一份相同且不可变字符串的方法,不同的值被存放在字符串的驻留池中,Python的驻留机制对相同的字符串只保留一份拷贝,后续创建相同字符串时,不会开辟新空间,而是把该字符串的地址赋给新创建的变量
1 |
|
-
触发驻留机制的几种情况(交互模式)
- 字符串的长度为0或1时
- 符合标识符的字符串
- 字符串只在编译时进行驻留,而非运行时
- [-5,256]之间的整数数字
-
sys中的intern方法强制2个字符串指向同一个对象
-
PyCharm对字符串进行了优化处理(只要内容相同即驻留)
-
字符串驻留机制的优缺点
- 当需要值相同的字符串时,可以直接从字符串池里拿来使用,避免频繁的创建和销毁,提升效率和节约内存,因此拼接字符串和修改字符串是会比较影响性能的。
- 在需要进行字符串拼接时,建议使用str类型的join方法,而非+ ,因为join()方法是先计算出所有字符中的长度,然后再拷贝,只new一次对象,效率要比"+"效率高
2、字符串的常用操作
(1)查询
方法 | 描述 |
---|---|
index() | 查找子串substr第一次出现的位置,如果查找的子串不存在时,则抛出ValueError |
rindex() | 查找子串substr最后一次出现的位置,如果查找的子串不存在时,则抛出ValueError |
find() | 查找子串substr第一次出现的位置,如果查找的子串不存在时,则返回 -1 |
rfind() | 查找子串substr最后一次出现的位置,如果查找的子串不存在时,则返回 -1 |
1 |
|
(2)大小写转换
方法 | 描述 |
---|---|
upper() | 把字符串中所有字符都转成大写字母; 产生了新的字符串 |
lower() | 把字符串中所有字符都转成小写字母; 产生了新的字符串 |
swapcase() | 把字符串中所有大写字母转成小写字母,把所有小写字母都转成大写字母; 产生了新的字符串 |
capitalize() | 把第一个字符转换为大写,把其余字符转换为小写; 产生了新的字符串 |
title() | 把每个单词的第一个字符转换为大写,把每个单词的剩余字符转换为小写; 产生了新的字符串 |
(3)字符串对齐
方法 | 描述 |
---|---|
center() | 居中对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则则返回原字符串 |
ljust() | 左对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则则返回原字符串 |
rjust() | 右对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则则返回原字符串 |
zfill() | 右对齐,左边用0填充,该方法只接收一个参数,用于指定字符串的宽度,如果指定的宽度小于等于字符串的长度,返回字符串本身 |
1 |
|
(4)字符串的分割
方法 | 描述 |
---|---|
split() | 从字符串的左边开始劈分,默认的劈分字符是空格字符串,返回的值都是一个列表; 以通过参数sep指定劈分字符串是的劈分符; 通过参数maxsplit指定劈分字符串时的最大劈分次数,在经过最大次劈分之后,剩余的子串会单独做为一部分 |
rsplit() | 从字符串的右边开始劈分,其他同split() |
1 |
|
ps: 可以这么写'hello|world|python'.split('|')'
(5)判断字符串
方法 | 描述 |
---|---|
isidentifier() | 判断指定的家符串是不是合法的标识符 |
isspace() | 判断指定的字符串是否全部由空白字符组成(回车、换行,水平制表符) |
isalpha() | 判断指定的字符串是否全部由字母组成(汉字也是) |
isdecimal() | 判断指定字符串是否全部由十进制的数字组成 |
isnumeric() | 判断指定的字符串是否全部由数字组成 |
isalnum() | 判断指定字符串是否全部由字母和数字组成 |
(6)字符串的替换与合并
方法 | 描述 |
---|---|
replace() | 第1个参数指定被替换的子串,第2个参数指定替换子串的字符串,该方法返回替换后得到的字符串,替换前的字符串不发生变化,调用该方法时可以通过第3个参数指定最大替换次数 省流:第1个参数:替换什么;第2个参数:替换成什么;第3个参数:最大替换几次; |
join() | 将列表或元组中的字符串合并成一个字符串 |
1 |
|
3、字符串的比较操作
- 运算符: >, >=, <, <=, ==, !=
- 比较规则:首先比较两个字符串中的第一个字符,如果相等则继续比较下一个字符,依次比较下去,直到两个字符串中的字符不相等时,其比较结果就是两个字符串的比较结果,两个字符串中的所有后续字符将不再被比较。
- 比较原理:两上字符进行比较时,比较的是其ordinal value(原始值),调用内置函数 ord() 可以得到指定字符的ordinal value。与内置函数ord()对应的是内置函数 chr() ,调用内置函数 chr() 时指定ordinal value可以得到其对应的字符。
1 |
|
4、字符串的切片操作
- 字符串是不可变类型
- 不具备增、删、改等操作
- 切片操作将产生新的对象
切片操作同列表str[start: end: step]
1 |
|
输出结果
1 |
|
5、格式化字符串
两种方式:
1 |
|
输出结果
1 |
|
6、编码、解码
-
为什么需要编码转换
-
编码解码的方式
- 编码:将字符串转换为二进制数据(bytes),
s.encode(encoding='GBK')
,GBK、UTF-8 - 解码:将bytes类型的数据转换成字符串类型,
byte.decode(encoding='GBK')
,编码解码的格式要一致
- 编码:将字符串转换为二进制数据(bytes),
1 |
|
六、函数
1、创建
1 |
|
示例:
1 |
|
2、函数调用的参数传递
- 位置实参
根据形参对应的位置进行实参传递 - 关键字实参
根据形参名称进行实参传递
1 |
|
3、参数传递的内存分析
内存分析图:
4、函数的返回值
-
如果函数没有返回值【函数执行完毕之后,不需要给调用处提供数据】return可以省略不写
如果没有return,则默认返回None
-
函数的返回值如果是1个,直接返回类型
-
函数的返回值如果是多个(
return a, b
),返回的结果为元组
1 |
|
输出结果
1 |
|
5、函数参数的定义
(1)默认值参数
函数定义时,给形参设置默认值,只有与默认值不符的时候才需要传递实参
举例:
1 |
|
(2)个数可变的位置参数
- 定义函数时,可能无法事先确定传递的位置实参的个数时,使用可变的位置参数
- 使用 * 定义个数可变的位置形参
- 结果为一个元组
1 |
|
(3)个数可变的关键字形参
- 定义函数时,无法事先确定传递的关键字实参的个数时,使用可变的关键字形参
- 使用 ** 定义个数可变的关键字形参
- 结果为一个字典
1 |
|
ps:
- 个数可变的位置参数和关键字形参都只能是一个
- 可以同时都有,但是个数可变的位置参数必须在写在前面
1 |
|
(4)参数使用总结
1 |
|
6、递归函数
-
递归的调用过程:
-
每递归调用一次函数,都会在栈内存分配一个栈帧,
-
每执行完一次函数,都会释放相应的空间
-
1 |
|
7、匿名函数
使用lambda来创建匿名函数,它是一个可以接收多个任意参数,并返回单个表达式的值的函数
1 |
|
七、bug、异常处理
1、bug的类型
-
粗心导致的语法错误
- 漏了末尾的冒号,如if语句,循环语句,else子句等
- 缩进错误,该缩进的没缩进,不该缩进的瞎缩进
- 把英文符号写成中文符号,比如说:引号,冒号,括号
- 字符串拼接的时候,把字符串和数字拼在一起
- 没有定义变量,比如说while的循环条件的变量
- "=="比较运算符和”=”赋值运算符的混用
-
知识点掌握不熟练
- 索引越界
- 内置函数还是对象方法
-
逻辑错误
-
被动掉坑
程序代码逻辑没有错,只是因为用户错误操作或者一些“例外情况"而导致的程序崩溃
解决:Python异常处理机制
2、Python异常处理机制
Python提供了异常处理机制,可以在异常出现时即时捕获,然后内部“消化”,让程序继续运行。
(1)try-except
(2)多个except结构
-
捕获异常的顺序按照先子类后父亲类的顺序,为了避免遗漏可能出现的异常,可以在最后增加
BaseException
1 |
|
(3)try-except-else
如果try块中没有抛出异常,则执行else块,如果try中抛出异常,则执行except块
1 |
|
(4)try-except-else-finally
finally块无论是否发生异常都会被执行,能常用来释放try块中申请的资源
1 |
|
3、Python中常见的异常
异常类型 | 描述 |
---|---|
ZeroDivisionError | 除(或取模)零(所有数据类型) |
IndexError | 序列中没有此索引(index) |
KeyError | 映射中没有这个键 |
NameError | 未声明/初始化对象(没有属性) |
SyntaxError | Python语法错误 |
ValueError | 传入无效参数 |
4、traceback模块
使用traceback模块打印异常信息
1 |
|
5、Pycharm程序调试
断点调试
八、类和对象
python中一切皆对象
1、创建类
语法:
1 |
|
类名规范:由一个或多个单词组成,每个单词的首字母大写
案例
1 |
|
- 类的组成
- 类属性
- 初始化方法
- 实例方法
- 静态方法
- 类方法
1 |
|
ps: self代表实例对象本身
2、创建对象
又称为类的实例化
语法:
1 |
|
举例:(使用上面的Student类)
1 |
|
输出为
3、类属性、类方法、静态方法的使用方法
(1)类属性
类中方法外的变量称为类变量,被该类的所有对象共享(类指针)
举例:(使用上面的Student类)
1 |
|
(2)类方法
使用
@classmethod
修饰的方法,使用类名直接访问的方法
1 |
|
(3)静态方法
使用
@staticmethod
修饰的方法,使用类名直接访问的方法
1 |
|
(4)实例方法
使用1:
1 |
|
使用2:
1 |
|
案例
1 |
|
4、动态绑定属性和方法
python是动态语言,在创建对象后,可以动态地绑定属性和方法
- 动态绑定属性
语法:
1 |
|
案例
1 |
|
内存图
- 动态绑定方法
语法:
1 |
|
案例
1 |
|
内存图类似上面的
5、面向对象的三大特征
- 封装: 提高程序的安全性
- 将数据 (属性)和行为(法)包装到类对象中。在方法内部对属性进行操作,在类对象的外部调用方法。这样就无需关心方法内部的具体实现细节,从而隔离了复这样杂度。
- 在Python中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前边使用两个
_
- 继承: 提高代码的复用性
- 多态: 提高代码的可扩展性和可维护性
(1)封装的实现
如果该属性不希望在类对象外部被访问,前边使用两个_
举例:
1 |
|
扩展:就是要访问__name
属性
1、dir(实例名)
1 |
|
2、找到属性并访问
1 |
|
所以可以访问,但是不要访问就好了
(2)继承的实现
语法:
1 |
|
- 如果一个类没有继承任何类,则默认继承object
- Python支持多继承
- 定义子类时,必须在其构造函数中调用父类的构造函数
案例
1 |
|
使用 super() 函数来调用父类
多继承以后再看吧。。。
方法重写
1 |
|
(3)多态的实现
简单地说,多态就是“具有多种形态”,它指的是:即便不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法
案例:
1 |
|
静态语言与动态语言
- 静态语言(JAVA)和动态语言关于多态的区别静态语言实现多态的三个必要条件
- 继承
- 方法重写
- 父类引用指向子类对象9
- 动态语言的多态崇尚“鸭子类型”当看到一只鸟走起来像鸭子、游泳起来像鸭子收起来也像鸭子,那么这只鸟就可以被称为鸭子。在鸭子类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为。
6、object类
- object类是所有类的父类,因此所有类都有object类的属性和方法
- 内置函数 dir() 可以查看指定对象所属性
- Object有一个 __str__() 方法,用于返回一个对于“对象的描述”,对应于内置函数str()经常用于print()方法,帮我们查看对象的信息,所以我们经常会对 __str__() 进行重写
案例:
1 |
|
输出为:
1 |
|
7、特殊的属性和方法
属性/方法 | 名称 | 描述 |
---|---|---|
特殊属性 | __dict__ |
获得类对象或实例对象所绑定的属性和方法的字典 |
特殊方法 | __len__() |
通过重写__len__() ,让内置函数len()的参数可以是自定义类型 |
特殊方法 | __add__() |
通过重写__add__() ,可是自定义对象具有”+“功能 |
特殊方法 | __new__() |
用于创建对象 |
特殊方法 | __init__() |
对创建的对象进行初始化 |
特殊属性
__dict__
1 |
|
输出为
1 |
|
特殊方法
__add__()
案例
1 |
|
__len__()
案例
1 |
|
__new__()
和__init__()
案例:
1 |
|
输出为
1 |
|
原理图
8、类的浅拷贝与深拷贝
-
变量的赋值操作
只是形成两个变量,实际上指向同一个对象
案例
1
2
3
4
5
6
7
8class A:
pass
a1 = A()
a2 = a1
print(id(a1)) # 输出为 2143666190896
print(id(a2)) # 输出为 2143666190896内存图
-
浅拷贝
python拷贝一般都是浅拷贝,拷贝时,对象包含的子对象内容不拷贝,因此,源对象和拷贝对象会引用同一对象
案例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20class CPU:
pass
class Disk:
pass
class Cumputer:
def __init__(self, cpu, disk):
self.cpu = cpu
self.disk = disk
cpu = CPU()
disk = Disk()
computer1 = Cumputer(cpu, disk)
# 浅拷贝
import copy
computer2 = copy.copy(computer1)
print(id(computer1), id(computer1.cpu), id(computer1.disk))
print(id(computer2), id(computer2.cpu), id(computer2.disk))输出为
1
21819258797744 1819258798032 1819258797792
1819258797552 1819258798032 1819258797792内存图
-
深拷贝
使用copy模块的 deepcopy() 函数,递归拷贝对象中包含的子对象、源对象和拷贝对象所有的子对象各不相同
案例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20class CPU:
pass
class Disk:
pass
class Cumputer:
def __init__(self, cpu, disk):
self.cpu = cpu
self.disk = disk
cpu = CPU()
disk = Disk()
computer1 = Cumputer(cpu, disk)
# 深拷贝
import copy
computer2 = copy.deepcopy(computer1)
print(id(computer1), id(computer1.cpu), id(computer1.disk))
print(id(computer2), id(computer2.cpu), id(computer2.disk))输出为
1
21859713646256 1859713646544 1859713646304
1859713645920 1859713644480 1859713864400内存图
九、模块、包
1、什么是模块、模块化编程的好处
- 模块英文为Modules
- 函数与模块的关系
- 一个模块中可以包含N多个函数(也可以N个类)
- 在Python中一个扩展名为 .py 的文件就是一个模块
- 使用模块的好处
- 方便其它程序和脚本的导入并使用
- 避免函数名和变量名冲突
- 提高代码的可维护性
- 提高代码的可重用性
2、导入模块
-
创建模块
- 新建一个 .py 文件,名称尽量不要与Python自带的标准模块名称相同
-
导入模块
-
只能导入包名和模块名
1
import 模块名称 [as别名]
-
可以导入包、模块、函数、变量、类
可以减少查询时间,提高访问速度1
from 模块名称 import 函数/变量/类
-
可以不用加模块名做前缀,简单但是一般不推荐
1
from 模块名称 import *
-
案例
1 |
|
导入自定义模块
calc.py文件内容
1 |
|
导入使用
1 |
|
文件命名不规范的这样导入(没有.py)
1 |
|
3、以主程序方式运行
在每个模块的定义中都包括一个记录模块名称的变量__name__
,程序可以检查该变量,以确定他们在哪个模块中执行。如果一个模块不是被导入到其它程序中执行,那么它可能在解释器的顶级模块中执行。顶级模块的__name__
变量的值为__main___
1 |
|
1 |
|
如果没有这么处理
calc.py内容
1 |
|
运行的内容
1 |
|
输出结果:
1 |
|
4、包
-
包是一个分层次的目录结构,它将一组功能相近的模块组织在一个目录下
-
作用:
- 代码规范
- 避免模块名称冲突
-
包与目录的区别
- 包含
_init__.py
文件的目录称为包_,告诉python将该目录作为一个包来处理 - 目录里通常不包含
_init__.py
文件
- 包含
-
包的导入
1
import 包名.模块名
案例
文件结构
1
2
3
4
5├───helloworld.py
├───directory
└───package
calc.py
__init__.py导入
1
2
3
4import package.calc
package.calc.mult(100, 200) # 输出为 计算结果为: 20000输出为
package.calc.div(100, 10) # 输出为 计算结果为: 10.0
5、Python中常用的内置模块
模块名 | 描述 |
---|---|
sys | 与Python解释器及其环境操作相关的标准库 |
time | 提供与时间相关的各种函数的标准库 |
os | 提供了访问操作系统服务功能的标准库 |
calendar | 提供与日期相关的各种函数的标准库 |
urllib | 用于读取来自网上(服务器)的数据标准库 |
json | 用于使用JSON序列化和反序列化对象 |
re | 用于在字符串中执行正则表达式匹配和替换 |
math | 提供标准算术运算函数的标准库 |
decimal | 用于进行精确控制运算精度、有效数位和四舍五入操作的十进制运算 |
logging | 提供了灵活的记录事件、错误、警告和调试信息等目志信息的功能 |
6、第三方模块的安装及使用
-
安装
1
pip install 模块名
未报错,安装成功
-
使用
import 模块名
1 |
|
模块无法生效
Pycharm无法解析
解决:配置Python Interpreter(Python解释器)
文件 -> 设置 -> 项目xxx -> Python解释器:
7、搜索路径
Python模块的导入需要路径搜索的过程
搜索路径:
1 |
|
不在同一目录下,需要将包、模块所在的路径添加进去
1 |
|
十、文件读写
1、文件读写原理
-
文件读写俗称"IO操作"
-
文件读写流程
2、文件的读写操作
-
使用内置函数 open()
语法格式
案例
1
2
3file = open('./data.txt', 'r', encoding='gbk')
print(file.readlines()) # 输出为 我是一个文件
file.close()
3、常用的文件打开模式
- 文件的类型(按文件的组织形式,文件分为以下两大类)
- 文本文件: 存储的是普通"字符"文本,默认为unicode字符集,可以使用记事本程序打开
- 二进制文件:把数据内容用"字节"进行存储,无法用记事本打开,必须使用专用的软件打开,举例,mp3音频文件
打开方式 | 描述 |
---|---|
r | 以只读的模式打开文件,文件指针将会放在文件的开头 |
w | 以只写的模式打开文件,如果文件不存在则创建,如果文件存在,则覆盖原有内容,文件指针在文件的开头 |
a | 以追加的模式打开文件,如果文件不存在则创建,文件指针在文件开头;如果文件存在,则在文件末尾追加内容,文件指在原文件的末尾 |
b | 以二进制的方式打开文件,不能单独使用,需要与其他模式一起使用,例如:rb、wb |
+ | 与读写的方式打开文件,不能单独使用,需要与其他模式一起使用,例如:a+ |
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() | 把缓冲区的内容写入文件,同时关闭文件,释放文件对象相关资源 |
案例
1 |
|
5、with语句(上下文管理器)
with语句可以自动的管理上下文资源,无论什么原因跳出with块,都能保证文件的正确关闭以此来达到释放资源的目的
语法
案例
1 |
|
上下文管理器
1 |
|
6、os模块
- os模块是Python内置的与操作系统功能和文件系统相关的模块,该模块中的语句的执行结果通常与操作系统有关,在不同的操作系统上运行,得到的结果可能不一样。
- os模块与os.path模块用于对目录或文件进行操作
案例
1 |
|
os模块操作目录的相关函数
函数 | 说明 |
---|---|
getcwd() | 返回当前工作目录 |
listdir(path) | 返回指定路径下的文件和目录 |
mkdir(path[, mode]) | 创建目录 |
makedirs(path1/path2…[, mode]) | 创建多级目录 |
rmdir(path) | 删除目录 |
removedirs(path1/path2…) | 删除多级目录 |
chdir(path) | 将path设置为当前工作目录 |
walk(path) | 返回指定路径下的文件和目录,以及子目录下的文件和目录 (8、案例中有专门的例子) |
案例:
1 |
|
7、os.path模块
相关函数
函数 | 说明 |
---|---|
abspath(path) | 用于获取文件或目录的绝对路径 |
exists(path) | 用于判断文件或目录是否存在,如果存在,返回True,否则返回False |
join(path, name) | 将目录与目录或者文件名拼接起来 |
split(path) | |
splitext(path) | 分离文件名和拓展名 |
basename(path) | 从一个目录中提取文件名 |
dirname(path) | 从一个路径中提取文件路径,不包括文件名 |
isdir(path) | 用于判断是否是路径 |
案例
1 |
|
输出为
1 |
|
8、案例
列出指定目录下的所有.py文件
1 |
|
walk()的使用
1 |
|
输出为
1 |
|
十一、实操案例
1、向文件输出内容
1 |
|
2、模拟高铁售票系统
安装模块
1 |
|
1 |
|
输出结果
1 |
|
3、创建虚拟环境
- 创建虚拟环境
1 |
|
运行:
进去scripts文件夹,执行active.bat
- 转移环境
1 |
|
接受
1 |
|