引言
Python 解释器
解释器存放在:<Python安装目录>/python.exe
Python解释器的作用是
将Python代码翻译成计算机认识的0和1并提交计算机执行
在解释器环境内可以一行行的执行我们输入的代码
也可以使用解释器程序,去执行”.py”代码文件
Python数据类型
常用的值类型Python中常用的有6种值(数据)的类型
字符串无法和非字符串变量进行拼接,因为类型不一致,无法接上,以下是错误的
name ="花花世界" year = 3623 print(name + "是" +year)
字符串格式化
多个变量占位 变量要用括号括起来 并按照占位的顺序填入
字符串格式化 - 数字精度控制
我们可以使用辅助符号"m.n"来控制数据的宽度和精度
m,控制宽度,要求是数字(很少使用),设置的宽度小于数字自身,不生效
.n,控制小数点精度,要求是数字,会进行小数的四舍五入
示例:
%5d:表示将整数的宽度控制在5位,如数字11,被设置为5d,就会变成:[空格][空格][空格]11,用三个空格补足宽度。
%5.2f:表示将宽度控制为5,将小数点精度设置为2
小数点和小数部分也算入宽度计算。如,对11.345设置了%7.2f 后,结果是:[空格][空格]11.35。2个空格补足宽度,小数部分限制2位精度后,四舍五入为 .35
%.2f:表示不限制宽度,只设置小数点精度为2,如11.345设置%.2f后,结果是11.35
通过语法:f"内容{变量}"的格式来快速格式化
这种写法不做精度控制 也不理会类型 适用于快速格式化字符串
input语句
获取的数据类型
无论键盘输入何种类型的数据
最终的结果都是:字符串类型的数据
for循环
同while循环不同,for循环是无法定义循环条件的。
只能从被处理的数据集中,依次取出内容进行处理。
所以,理论上讲,Python的for循环无法构建无限循环(被处理的数据集不可能无限大)
for循环的注意点
无法定义循环条件,只能被动取出数据处理
要注意,循环内的语句,需要有空格缩进
语法中的:待处理数据集,严格来说,称之为:可迭代类型
可迭代类型指,其内容可以一个个依次取出的一种类型,包括:字符串 列表 元组
表示,从容器内,依次取出元素并赋值到临时变量上。
在每一次的循环中,我们可以对临时变量(元素)进行处理。
while循环和for循环,都是循环语句,但细节不同:
在循环控制上:
while循环可以自定循环条件,并自行控制
for循环不可以自定循环条件,只可以一个个从容器内取出数据
在无限循环上:
while循环可以通过条件控制做到无限循环
for循环理论上不可以,因为被遍历的容器容量不是无限的
在使用场景上:
while循环适用于任何想要循环的场景
for循环适用于,遍历数据容器的场景或简单的固定次数循环场景
range语句
语法1: range(num)
获取一个从0开始,到num结束的数字序列(不含num本身)
如range(5)取得的数据是:[0, 1, 2, 3, 4]
语法2:range(num1,num2)
获得一个从num1开始,到num2结束的数字序列(不含num2本身)
如,range(5, 10)取得的数据是:[5, 6, 7, 8, 9]
语法3:range(num1,num2,step)
获得一个从num1开始,到num2结束的数字序列(不含num2本身)
数字之间的步长,以step为准(step默认为1)
如,range(5, 10, 2)取得的数据是:[5, 7, 9]
None类型的应用场景
数据容器
学习数据容器,就是为了批量存储或批量使用多份数据
数据容器可以从以下视角进行简单的分类:
是否支持下标索引
支持:列表、元组、字符串 - 序列类型
不支持:集合、字典 - 非序列类型
是否支持重复元素:
支持:列表、元组、字符串 - 序列类型
不支持:集合、字典 - 非序列类型
是否可以修改
支持:列表、集合、字典
不支持:元组、字符串
列表
列表可以一次存储多个数据,且可以为不同的数据类型,支持嵌套
列表的用法
查找某元素的下标
功能:查找指定元素在列表的下标,如果找不到,报错ValueError
语法:列表.index(元素)
index就是列表对象(变量)内置的方法(函数)
修改特定位置(索引)的元素值:
语法:列表[下标] = 值
可以使用如上语法,直接对指定下标(正向、反向下标均可)的值进行:重新赋值(修改)
插入元素:
语法:列表.insert(下标, 元素),在指定的下标位置,插入指定的元素
追加元素:
语法:列表.append(元素),将指定元素,追加到列表的尾部
追加元素方式2:
语法:列表.extend(其它数据容器),将其它数据容器的内容取出,依次追加到列表尾部
删除元素:
语法1: del 列表[下标]
语法2:列表.pop(下标)
删除某元素在列表中的第一个匹配项
语法:列表.remove(元素)
清空列表内容,语法:列表.clear()
统计某元素在列表内的数量 语法:列表.count(元素)
统计列表内,有多少元素 语法:len(列表)
可以得到一个int数字,表示列表内的元素数量
列表的sort方法
列表.sort(key=选择排序依据的函数, reverse=True|False)
参数key,是要求传入一个函数,表示将列表的每一个元素都传入函数中,返回排序的依据
参数reverse,是否反转排序结果,True表示降序,False表示升序
元组一旦定义完成,就不可修改
注意:元组只有一个数据,这个数据后面要添加逗号
元组由于不可修改的特性,所以其操作方法非常少
可以修改元组内的list的内容(修改元素、增加、删除、反转等)
字符串
同元组一样,字符串是一个:无法修改的数据容器。
所以:修改指定下标的字符 (如:字符串[0] = “a”)
移除特定下标的字符 (如:del 字符串[0]、字符串.remove()、字符串.pop()等)
追加字符等 (如:字符串.append())均无法完成。如果必须要做,只能得到一个新的字符串,旧的字符串是无法修改
字符串的分割
语法:字符串.split(分隔符字符串)
功能:按照指定的分隔符字符串,将字符串划分为多个字符串,并存入列表对象中
注意:字符串本身不变,而是得到了一个列表对象
字符串的规整操作
(去前后空格) 语法:字符串.strip()
(去前后指定字符串) 语法:字符串.strip(字符串)
注意,传入的是“12” 其实就是:”1”和”2”都会移除,是按照单个字符。
统计字符串中某字符串的出现次数
语法:字符串.count(字符串)
数据容器(序列)的切片
序列是指:内容连续、有序,可使用下标索引的一类数据容器
列表、元组、字符串,均可以可以视为序列。
切片:从一个序列中,取出一个子序列
语法:序列[起始下标:结束下标:步长]
表示从序列中,从指定位置开始,依次取出元素,到指定位置结束,得到一个新序列:
起始下标表示从何处开始,可以留空,留空视作从头开始
结束下标(不含)表示何处结束,可以留空,留空视作截取到结尾
步长表示,依次取元素的间隔
步长1表示,一个个取元素
步长2表示,每次跳过1个元素取
步长N表示,每次跳过N-1个元素取
步长为负数表示,反向取(注意,起始下标和结束下标也要反向标记)
注意,此操作不会影响序列本身,而是会得到一个新的序列(列表、元组、字符串)
集合
集合是无序的,所以集合不支持:下标索引访问
集合的相关操作
添加新元素
语法:集合.add(元素)。将指定元素,添加到集合内
结果:集合本身被修改,添加了新元素
移除元素
语法:集合.remove(元素),将指定元素,从集合内移除
结果:集合本身被修改,移除了元素
从集合中随机取出元素
语法:集合.pop(),功能,从集合中随机取出一个元素
结果:会得到一个元素的结果。同时集合本身被修改,元素被移除
清空集合
语法:集合.clear(),功能,清空集合
结果:集合本身被清空
取出2个集合的差集
语法:集合1.difference(集合2),功能:取出集合1和集合2的差集(集合1有而集合2没有的)
结果:得到一个新集合,集合1和集合2不变
消除2个集合的差集
语法:集合1.difference_update(集合2)
功能:对比集合1和集合2,在集合1内,删除和集合2相同的元素。
结果:集合1被修改,集合2不变
2个集合合并
语法:集合1.union(集合2)
功能:将集合1和集合2组合成新集合
结果:得到新集合,集合1和集合2不变
字典
字典的定义,同样使用{},不过存储的元素是一个个的:键值对
使用{}存储原始,每一个元素是一个键值对
每一个键值对包含Key和Value(用冒号分隔)
键值对之间使用逗号分隔
Key和Value可以是任意类型的数据(key不可为字典)
Key不可重复,重复会对原有数据覆盖
字典的操作
字典同集合一样,不可以使用下标索引
但是字典可以通过Key值来取得对应的Value
新增元素
语法:字典[Key] = Value,结果:字典被修改,新增了元素
更新元素
语法:字典[Key] = Value,结果:字典被修改,元素被更新
注意:字典Key不可以重复,所以对已存在的Key执行上述操作,就是更新Value值
删除元素
语法:字典.pop(Key),结果:获得指定Key的Value,同时字典被修改,指定Key的数据被删除
清空字典
语法:字典.clear(),结果:字典被修改,元素被清空
获取全部的key
语法:字典.keys(),结果:得到字典中的全部Key
遍历字典
语法:for key in 字典
通用排序功能
sorted(容器, [reverse=True])
将给定容器进行排序
注意,排序后都会得到列表(list)对象。
容器通用功能总览
函数
global关键字
多个返回值
按照返回值的顺序,写对应顺序的多个变量接收即可
变量之间用逗号隔开
支持不同类型的数据return
函数参数种类
位置参数:调用函数时根据函数定义的参数位置来传递参数
传递的参数和定义的参数的顺序及个数必须一致
关键字参数:函数调用时通过“键=值”形式传递参数.
作用: 可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求.
函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序
缺省参数:缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用).
作用: 当调用函数时没有传递参数, 就会使用默认是用缺省参数对应的值
不定长参数:不定长参数也叫可变参数. 用于不确定调用的时候会传递多少个参数(不传参也可以)的场景.
作用: 当调用函数时不确定参数个数时, 可以使用不定长参数
不定长参数的类型:
①位置传递
②关键字传递
①位置传递
注意:
传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是位置传递
②关键字传递
注意:
参数是“键=值”形式的形式的情况下, 所有的“键=值”都会被kwargs接受, 同时会根据“键=值”组成字典.
函数作为参数传递
函数compute,作为参数,传入了test_func函数中使用。
test_func需要一个函数作为参数传入,这个函数需要接收2个数字进行计算,计算逻辑由这个被传入函数决定
compute函数接收2个数字对其进行计算,compute函数作为参数,传递给了test_func函数使用
最终,在test_func函数内部,由传入的compute函数,完成了对数字的计算操作
所以,这是一种,计算逻辑的传递,而非数据的传递。
就像上述代码那样,不仅仅是相加,相见、相除、等任何逻辑都可以自行定义并作为函数传入。
lambda匿名函数
函数的定义中
def关键字,可以定义带有名称的函数
lambda关键字,可以定义匿名函数(无名称)
有名称的函数,可以基于名称重复使用。
无名称的匿名函数,只可临时使用一次。
lambda 是关键字,表示定义匿名函数
传入参数表示匿名函数的形式参数,如:x, y 表示接收2个形式参数
函数体,就是函数的执行逻辑,要注意:只能写一行,无法写多行代码
文件操作
在Python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件,语法如下
open(name, mode, encoding)
name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径)。
mode:设置打开文件的模式(访问模式):只读、写入、追加等。
encoding:编码格式(推荐使用UTF-8)
f = open('python.txt', 'r', encoding=”UTF-8)
# encoding的顺序不是第三位,所以不能用位置参数,用关键字参数直接指定
注意:此时的`f`是`open`函数的文件对象,对象是Python中一种特殊的数据类型,拥有属性和方法,可以使用对象.属性或对象.方法对其进行访问,后续面向对象课程会给大家进行详细的介绍。
mode常用的三种基础访问模式
读操作相关方法
read()方法:文件对象.read(num)
num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据。
readlines()方法:
readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素。
readline()方法:一次读取一行内容
for循环读取文件行
with open 语法
写操作
文件如果不存在,使用”w”模式,会创建新文件
文件如果存在,使用”w”模式,会将原有内容清空
直接调用write,内容并未真正写入文件,而是会积攒在程序的内存中,称之为缓冲区
当调用flush的时候,内容会真正写入文件
这样做是避免频繁的操作硬盘,导致效率下降(攒一堆,一次性写磁盘)
close()方法,带有flush()方法的功能
1. 追加写入文件使用open函数的”a”模式进行写入
2. 追加写入的方法有(和w模式一致):
wirte(),写入内容
flush(),刷新内容到硬盘中
3. 注意事项:
a模式,文件不存在,会创建新文件
a模式,文件存在,会在原有内容后面继续写入
可以使用”\n”来写出换行符
异常、模块与包
异常
异常就是程序运行的过程中出现了错误
捕获常规异常
捕获指定异常
捕获多个异常
当捕获多个异常时,可以把要捕获的异常类型的名字,放到except 后,并使用元组的方式进行书写。
捕获异常并输出描述信息
捕获所有异常
else表示的是如果没有异常要执行的代码。
finally表示的是无论是否异常都要执行的代码,例如关闭文件。
异常的传递
异常是具有传递性的
当函数func01中发生异常, 并且没有捕获处理这个异常的时候, 异常
会传递到函数func02, 当func02也没有捕获处理这个异常的时候
main函数会捕获这个异常, 这就是异常的传递性.
提示:
当所有函数都没有捕获异常的时候, 程序就会报错
利用异常具有传递性的特点, 当我们想要保证程序不会因为异常崩溃的时候,
就可以在main函数中设置异常捕获, 由于无论在整个程序哪里发生异常, 最终都
会传递到main函数中, 这样就可以确保所有的异常都会被捕获
Python 模块(Module)
是一个 Python 文件,以 .py 结尾. 模块能定义函数,类和变量,模块里也能包含可执行的代码.
模块的作用: python中有很多各种不同的模块, 每一个模块都可以帮助我们快速的实现一些功能, 比如实现和时间相关的功能就可以使用time模块
我们可以认为一个模块就是一个工具包, 每一个工具包中都有各种不同的工具供我们使用进而实现各种不同的功能.
大白话:模块就是一个Python文件,里面有类、函数、变量等,我们可以拿过来用(导入模块去使用)
模块在使用前需要先导入 导入的语法如下:
常用的组合形式如:
import 模块名
from 模块名 import 类、变量、方法等
from 模块名 import *
import 模块名 as 别名
from 模块名 import 功能名 as 别名
Python中已经帮我们实现了很多的模块. 不过有时候我们需要一些个性化的模块, 这里就可以通过自定义模块实现, 也就是自己制作一个模块
每个Python文件都可以作为一个模块,模块的名字就是文件的名字. 也就是说自定义模块名必须要符合标识符命名规则
注意事项:当导入多个模块的时候,且模块内有同名功能. 当调用这个同名功能的时候,调用到的是后面导入的模块的功能
如果一个模块文件中有`__all__`变量,当使用`from xxx import *`导入时,只能导入这个列表中的元素
什么是Python包
从物理上看,包就是一个文件夹,在该文件夹下包含了一个 __init__.py 文件,该文件夹可用于包含多个模块文件
从逻辑上看,包的本质依然是模块
包的作用:
当我们的模块文件越来越多时,包可以帮助我们管理这些模块, 包的作用就是包含多个模块,但包的本质依然是模块
导入包
方式一:
import 包名.模块名
包名.模块名.目标
方式二:
注意:必须在`__init__.py`文件中添加`__all__ = []`,控制允许导入的模块列表
my_module1报红证明不可用
注意:
__all__针对的是 ’ from ... import * ‘ 这种方式
对 ‘ import xxx ’ 这种方式无效
1. 什么是Python的包?
包就是一个文件夹,里面可以存放许多Python的模块(代码文件),通过包,在逻辑上将一批模块归为一类,方便使用。
2. __init__.py文件的作用?
创建包会默认自动创建的文件,通过这个文件来表示一个文件夹是Python的包,而非普通的文件夹。
3. __all__变量的作用?
同模块中学习到的是一个作用,控制 import * 能够导入的内容
第三方包
我们知道,包可以包含一堆的Python模块,而每个模块又内含许多的功能。
所以,我们可以认为:一个包,就是一堆同类型功能的集合体。
在Python程序的生态中,有许多非常多的第三方包(非Python官方),可以极大的帮助我
们提高开发效率,如:
科学计算中常用的:numpy包
数据分析中常用的:pandas包
大数据计算中常用的:pyspark、apache-flink包
图形可视化常用的:matplotlib、pyecharts
人工智能常用的:tensorflow
等
这些第三方的包,极大的丰富了Python的生态,提高了开发效率。
但是由于是第三方,所以Python没有内置,所以我们需要安装它们才可以导入使用哦。
安装第三方包 - pip
pip install 包名称
即可通过网络快速安装第三方包