一、Python基础语法
1.1、字面量(常量)
类型 | 描述 | 说明 |
数字(Number) |
•整数(int)
•浮点数(float)
•复数(complex)
•布尔(bool)
| 整数(int),如:10、-10 浮点数(float),如:13.14、-13.14 复数(complex),如:4+3j,以j结尾表示复数 即真和假,True表示真,False表示假。 True本质上是一个数字记作1,False记作0 |
字符串(String) | 描述文本的数据类型 | 字符串(string)由任意数量的字符组成 |
列表(List) | 有序的可变序列 | Python中使用最频繁的数据类型,可有序记录一堆数据 |
元组(Tuple) | 有序的不可变序列 | 可有序记录一堆不可变的Python数据集合 |
集合(Set) | 无序不重复集合 | 可无序记录一堆不重复的Python数据集合 |
字典(Dictionary) | 无序Key-Value集合 | 可无序记录一堆Key-Value型的Python数据集合 |
1.2、注释
单行注释:以 #开头,#右边 的所有文字当作说明,起辅助说明作用。
多行注释:以 一对三个双引号 ("""...""")引起来来解释说明一段代码的作用 。
1.3、变量
变量:在程序运行时,能储存计算结果或能表示值的抽象概念。变量的目的是存储运行过程的数据,存储的目的是为了重复使用 ,变量的特征是值可以改变。
1.4、数据类型转换
通过type()语句来得到数据的类型:type(被查看类型的数据)
定义字符串:单引号、双引号、三引号(一堆三个双引号的范围内,均是字符串)
int(x):将 x 转换为整数。float(x):将 x 转换为浮点数。str(x):将对象 x 转换为字符串。
任何类型都可以通过str()转换成字符串;字符串内必须真的是数字,才可以将字符串转换为数字。
1.5、标识符
定义:是用户在编程的时候所使用的一系列名字,用于给变量、类、方法等命名。
命名规范:内容限定,大小写敏感,不可使用关键字;英文、中文、数字、下划线;不推荐中文,不可用数字开头。
1.6、运算符
算术运算符 | 描述 | 实例 |
+ | 加 | 两个对象相加 a + b 输出结果 30 |
- | 减 | 得到负数或是一个数减去另一个数 a - b 输出结果 -10 |
* | 乘 | 两个数相乘或是返回一个被重复若干次的字符串 a * b 输出结果 200 |
/ | 除 | b / a 输出结果 2 |
// | 取整除 | 返回商的整数部分 9//2 输出结果 4 , 9.0//2.0 输出结果 4.0 |
% | 取余 | 返回除法的余数 b % a 输出结果 0 |
** | 指数 | a**b 为10的20次方, 输出结果 100000000000000000000 |
赋值运算符 | 描述 | 实例 |
= | 赋值运算符 | 把 = 号右边的结果 赋给 左边的变量,如 num = 1 + 2 * 3, 结果num的值为7 |
复合运算符 | 描述 | 实例 |
+= | 加法赋值运算符 | c += a 等效于 c = c + a |
-= | 减法赋值运算符 | c -= a 等效于 c = c - a |
*= | 乘法赋值运算符 | c *= a 等效于 c = c * a |
/= | 除法赋值运算符 | c /= a 等效于 c = c / a |
%= | 取模赋值运算符 | c %= a 等效于 c = c % a |
**= | 幂赋值运算符 | c **= a 等效于 c = c ** a |
//= | 取整除赋值运算符 | c //= a 等效于 c = c // a |
1.7、字符串扩展
定义方式:
单引号定义法,可以内含双引号,双引号定义法,可以内含单引号,可以使用转移字符(\)来将引号解除效用,变成普通字符串。三引号定义法,和多行注释的写法一样,同样支持换行操作,使用变量接收它,它就是字符串,不使用变量接收它,就可以作为多行注释使用。
字符串拼接:
两个字符串(文本)字面量,通过+号即可完成;无法和非字符串进行拼接(不能自动转型)
字符串格式1:
"%占位符1...%占位符2" % (变量1,变量2...)
message = " 我是:%s,我成立于:%d,我今天的股价是:%f " %(name,year,stock)
%s | 将内容转换成字符串,放入占位位置 |
%d | 将内容转换成整数,放入占位位置 |
%f | 将内容转换成浮点数,放入占位位置 |
字符串格式化精度:
使用辅助符号"m.n"来控制数据的宽度和精度。
m,控制宽度,要求是数字(很少使用),设置的宽度小于数字自身,不生效。
n,控制小数点精度,要求是数字,会进行小数的四舍五入。
%5d:表示将整数的宽度控制在5位,如数字11,被设置为5d,就会变成:[空格][空格][空格]11,用三个空格补足宽度。%5.2f:表示将宽度控制为5,将小数点精度设置为2。小数点和小数部分也算入宽度计算。
字符串格式化2:
f"{变量} {变量}"的方式进行快速格式化,不理会类型,不做精度控制
message = f" 我是:{name},我成立于:{year},我今天的股价是:{stock} "
表达式格式化:
表达式:一条具有明确执行结果的代码语句。在变量定义的时候,如 age = 11 + 11,等号右侧的就是表达式,也就是有具体的结果,将结果赋值给了等号左侧的变量。
在无需使用变量进行数据存储的时候,可以直接格式化表达式,简化代码。
f"{表达式}";"%s\%d\%f" % (表达式、表达式、表达式)
1.8、数据输入
print("请告诉我你是谁")
name = input()
#开始键盘敲名字
print("get! 你是:%s" % name)
#返回的永远是字符串类型
二、Python函数
1.1、函数定义
函数:是组织好的,可重复使用的,用来实现特定功能的代码段。•将功能封装在函数内,可供随时随地重复利用,提高程序的复用性,减少重复性代码,提高开发效率。
def 函数名(传入参数)
函数体
return 返回值
① 参数如不需要,可以省略
② 返回值如不需要,可以省略
③ 函数必须先定义后使用
Python中有一个特殊的字面量:None,其类型是:<class 'NoneType'>
无返回值的函数,实际上就是返回了:None这个字面量
None表示:空的、无实际意义的意思
函数返回的None,就表示,这个函数没有返回什么有意义的内容。
也就是返回了空的意思。
在if判断中,None等同于False
定义变量,但暂时不需要变量有具体值,可以用None来代替
1.2、局部变量VS全局变量
局部变量是定义在函数体内部的变量,即只在函数体内部生效。在函数体内部,临时保存数据,即当函数调用完成后,则销毁局部变量。
全局变量指的是在函数体内、外都能生效的变量。使用 global关键字 可以在函数内部声明变量为全局变量。
1.3、多返回值函数
如果一个函数如些两个return,只执行了第一个return,原因是因为return可以退出当前函数,
导致return下方的代码不执行。
如果一个函数要有多个返回值,按照返回值的顺序,写对应顺序的多个变量接收即可,变量之间用逗号隔开,支持不同类型的数据return。
def return_num():
return 1
return 2
result = return_num()
print(result)
结果:1
def return_num():
return 1,2
x,y = return_num()
print(x)
print(y)
结果:1 2
1.4、函数多种传参方式
def user_info(name,age,gender):
print(f'你的名字是{name},你的年龄是{age},你的性别是{gender}')
一、位置参数:调用函数时根据函数定义的参数位置来传递参数
user_info('Tom','20','男')
二、关键字参数:函数调用时通过“键=值”形式传递参数.
可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求.
函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,
但关键字参数之间不存在先后顺序
#关键字传参:
user_info(name='Tom',age='20',gender='男')
#不按顺序传参
user_info(age='20',name='Tom',gender='男')
#和位置参数混用,位置参数必须在前,且匹配参数顺序
user_info('Tom',gender='男',age='20')
三、缺省参数:缺省参数也叫默认参数,用于定义函数,为参数提供默认值,
调用函数时可不传该默认参数的值,所有位置参数必须出现在默认参数前,包括函数定义和调用
作用: 当调用函数时没有传递参数, 就会使用默认是用缺省参数对应的值.
函数调用时,如果为缺省参数传值则修改默认参数值, 否则使用这个默认值
def user_info(name,age,gender='女'):
print(f'你的名字是{name},你的年龄是{age},你的性别是{gender}')
user_info(name='Tom',age='20')
user_info(name='Tom',age='20',gender='男')
四、不定长参数:也叫可变参数. 用于不确定调用的时候会传递多少个参数(不传参也可以)的场景
作用: 当调用函数时不确定参数个数时, 可以使用不定长参数
不定长参数的类型:位置传递;关键字传递
#位置传递
def user_info(*args):
print(args)
user_info('Tom')
user_info('18')
传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),
args是元组类型,这就是位置传递.
#关键字传递
def user_info(**kwargs):
print(kwargs)
user_info(name='Tom',age='18',id='4335')
参数是“键=值”形式的形式的情况下, 所有的“键=值”都会被kwargs接受, 同时会根据“键=值”组成字典.
五、函数作为参数传递
函数作为参数传递是计算逻辑的传递,而非数据的传递,任何逻辑都可以自行定义并作为函数传入
def test(complete):
result = complete(1,2)
print(result)
def complete(x,y):
return x + y
1.5、匿名函数
函数的定义中
def关键字,可以定义带有名称的函数
lambda关键字,可以定义匿名函数(无名称)
有名称的函数,可以基于名称重复使用。
无名称的匿名函数,只可临时使用一次。
匿名函数定义语法:lamda 传入参数:函数体(一行代码)
lambda 是关键字,表示定义匿名函数 传入参数表示匿名函数的形式参数,如:x, y 表示接收2个形式参数 函数体,就是函数的执行逻辑,要注意:只能写一行,无法写多行代码
def test(complete):
result = complete(1,2)
print(result)
def complete(x,y):
return x + y
def test(complete):
result = complete(1,2)
print(result)
test(lamda x, y: x + y)
三、数据容器
定义:一种可以容纳多份数据的数据类型,容纳的每一份数据称之为1个元素每一个元素,可以是任意类型的数据。根据特点的不同:是否支持重复元素、是否可以修改、是否有序,分为5类列表(list)、元组(tuple)、字符串(str)、集合(set)、字典(dict)。
1.1、列表
列表定义:
字面量
[元素1,元素2,元素3,...]
定义变量
变量名称 = [元素1,元素2,元素3,...]
定义空列表
变量名称 = []
变量名称 = list()
列表索引:
列表中的每一个元素,都有其位置下标索引,从前向后的方向,从0开始,依次递增
或者,可以反向索引,也就是从后向前:从-1开始,依次递减(-1、-2、-3......)
列表常用操作:
列表.append(元素) :向列表中追加一个元素
列表.extend(容器) :将数据容器的内容依次取出,追加到列表尾部
列表.insert(下标, 元素):在指定下标处,插入指定的元素
del 列表[下标] :删除列表指定下标元素
列表.pop(下标) :删除列表指定下标元素
列表.remove(元素) :从前向后,删除此元素第一个匹配项
列表.clear() :清空列表
列表.count(元素) :统计此元素在列表中出现的次数
列表.index(元素) :查找指定元素在列表的下标,找不到报错ValueError
len(列表) :统计容器内有多少元素
列表特点:
可以容纳多个元素(上限为2**63-1、9223372036854775807个)
可以容纳不同类型的元素(混装)
数据是有序存储的(有下标序号)
允许重复数据存在
可以修改(增加或删除元素等)
1.2、元组
元组定义:
定义元组使用小括号,且使用逗号隔开各个数据,数据可以是不同的数据类型。
变量名称 = (元素1,元素2,元素3,...)
如果元组只有一个数据,这个数据后面要添加逗号
变量名称 = (元素1,)
元组索引和列表索引相同
元组常用操作:
元组由于不可修改的特性,所以其操作方法非常少。
不可以修改元组的内容,否则会直接报错
可以修改元组内的list的内容(修改元素、增加、删除、反转等)
不可以替换list为其它list或其它类型
index() :查找某个数据,如果数据存在返回对应的下标,否则报错
count() :统计某个数据在当前元组出现的次数
len(元组) :统计元组内的元素个数
元组特点:
可以容纳多个数据
可以容纳不同类型的数据(混装)
数据是有序存储的(下标索引)
允许重复数据存在
不可以修改(增加或删除元素等)
与list相同只是不能修改
1.3、字符串
字符串定义(上面有)
字符串索引与列表相同
字符串常用操作:
字符串比较大小:从头到尾,一位位进行比较,其中一位大,后面就无需比较了。
字符串[下标] :根据下标索引取出特定位置字符
字符串.index(字符串) :查找给定字符的第一个匹配项的下标
字符串.replace(str1, str2) :将字符串内的全部字符串1,替换为字符串2
不会修改原字符串,而是得到一个新的
字符串.split(字符串) :按照给定字符串,对字符串进行分隔
不会修改原字符串,而是得到一个新的列表
字符串.strip() :移除首尾的空格和换行符
字符串.strip(字符串) :移除首尾的指定字符串
字符串.count(字符串) :统计字符串内某字符串的出现次数
len(字符串) : 统计字符串的字符个数
字符串特点:
只可以存储字符串
长度任意(取决于内存大小)
支持下标索引
允许重复字符串存在
不可以修改(增加或删除元素等)
与元组一样不能修改
1.4、序列
序列定义:
内容连续、有序,可使用下标索引的一类数据容器
列表、元组、字符串,均可以可以视为序列。
序列支持切片,即:列表、元组、字符串,均支持进行切片操作
切片:从一个序列中,取出一个子序列
语法:序列[起始下标:结束下标:步长]
表示从序列中,从指定位置开始,依次取出元素,到指定位置结束,得到一个新序列:
起始下标表示从何处开始,可以留空,留空视作从头开始
结束下标(不含)表示何处结束,可以留空,留空视作截取到结尾
步长表示,依次取元素的间隔
步长1表示,一个个取元素
步长2表示,每次跳过1个元素取
步长N表示,每次跳过N-1个元素取
步长为负数表示,反向取(注意,起始下标和结束下标也要反向标记)
切片操作不会影响序列本身,而是会得到一个新的序列(列表、元组、字符串)
1.5、集合
集合定义:
字面量
{元素1,元素2,元素3,...}
定义变量
变量名称 = {元素1,元素2,元素3,...}
定义空列表
变量名称 = set()
集合不支持下标索引访问
集合常见操作:
集合.add(元素) :集合内添加一个元素
集合.remove(元素) :移除集合内指定的元素
集合.pop() :从集合中随机取出一个元素
集合.clear() :将集合清空
集合1.difference(集合2) :得到一个新集合,内含2个集合的差集
原有的2个集合内容不变
集合1.difference_update(集合2):在集合1中,删除集合2中存在的元素
集合1被修改,集合2不变
集合1.union(集合2) :得到1个新集合,内含2个集合的全部元素
原有的2个集合内容不变
len(集合) :得到一个整数,记录了集合的元素数量
集合特点:
可以容纳多个数据
可以容纳不同类型的数据(混装)
数据是无序存储的(不支持下标索引)
不允许重复数据存在
可以修改(增加或删除元素等)
1.6、字典
字典定义:
与集合一样使用{},不过存储的元素是一个个的:键值对
每一个键值对包含Key和Value(用冒号分隔)
键值对之间使用逗号分隔
Key和Value可以是任意类型的数据(key不可为字典)
Key不可重复,重复会对原有数据覆盖
字典字面量:
{key:valua,key:valua,key:valua...}
字典变量:
my_dict = {key:valua,key:valua,key:valua...}
定义空字典:
my_dict = {}
my_dict = dict()
字典不支持下标索引,通过Key值来取得对应的Value
字典常用操作:
字典[Key]:获取指定Key对应的Value值
字典[Key] = Value:添加或更新键值对
字典.pop(Key):取出Key对应的Value并在字典内删除此Key的键值对
字典.clear():清空字典
字典.keys():获取字典的全部Key,可用于for循环遍历字典
len(字典):计算字典内的元素数量
字典特点:
可以容纳多个数据
可以容纳不同类型的数据
每一份数据是KeyValue键值对
可以通过Key获取到Value,Key不可重复(重复会覆盖)
不支持下标索引
可以修改(增加或删除更新元素等)
支持for循环,不支持while循环
1.7、数据容器对比
列表 | 元组 | 字符串 | 集合 | 字典 | |
元素数量 | 支持多个 | 支持多个 | 支持多个 | 支持多个 | 支持多个 |
元素类型 | 任意 | 任意 | 仅字符 | 任意 | Key:Value Key:除字典外任意类型 Value:任意类型 |
下标索引 | 支持 | 支持 | 支持 | 不支持 | 不支持 |
重复元素 | 支持 | 支持 | 支持 | 不支持 | 不支持 |
可修改性 | 支持 | 不支持 | 不支持 | 支持 | 支持 |
数据有序 | 是 | 是 | 是 | 否 | 否 |
使用场景 | 可修改、可重复的一批数据记录场景 | 不可修改、可重复的一批数据记录场景 | 一串字符的记录场景 | 不可重复的数据记录场景 | 以Key检索Value的数据记录场景 |
1.8、数据容器通用功能:
功能 | 描述 |
通用for循环 | 遍历容器(字典是遍历key) |
max() | 容器内最大元素 |
min() | 容器内最小元素 |
len() | 容器元素个数 |
list() | 转换为列表 |
tuple() | 转换为元组 |
str() | 转换为字符串 |
set() | 转换为集合 |
sorted(序列, [reverse=True]) | 排序,reverse=True表示降序 得到一个排好序的列表 |
四、文件操作
1.1、文件读取
打开文件:
open(name, mode, encoding)
name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径)。
mode:设置打开文件的模式(访问模式):只读、写入、追加等。
encoding:编码格式(推荐使用UTF-8)
f = open('python.txt', 'r', encoding='UTF-8')
# encoding的顺序不是第三位,所以不能用位置参数,用关键字参数直接指定
r:以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
w:打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,
原有内容会被删除。如果该文件不存在,创建新文件。
a:打开一个文件用于追加。如果该文件已存在,新的内容将会被写入到已有内容之后。
如果该文件不存在,创建新文件进行写入。
读取文件:
文件对象.read(num):
num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,
那么就表示读取文件中所有的数据。
readlines()方法:
readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,
其中每一行的数据为一个元素。
readline()方法:一次读取一行内容
f = open('python.txt')
content = f.readlines()
# ['hello world\n', 'abcdefg\n', 'aaa\n', 'bbb\n', 'ccc']
print(content)
# 关闭文件
f.close()
for line in open("python.txt", "r"):
print(line)# 每一个line临时变量,就记录了文件的一行数据
f = open("python.txt", "r")
f.close()
# 最后通过close,关闭文件对象,也就是关闭对文件的占用
# 如果不调用close,同时程序没有停止运行,那么这个文件将一直被Python程序占用
with open("python.txt", "r") as f:
f.readlines()
# 通过在with open的语句块中对文件进行操作
# 可以在操作完成后自动关闭close文件,避免遗忘掉close方法
操作 | 功能 |
文件对象 = open(file, mode, encoding) | 打开文件获得文件对象 |
文件对象.read(num) | 读取指定长度字节 不指定num读取文件全部 |
文件对象.readline() | 读取一行 |
文件对象.readlines() | 读取全部行,得到列表 |
for line in 文件对象 | for循环文件行,一次循环得到一行数据 |
文件对象.close() | 关闭文件对象 |
with open() as f | 通过with open语法打开文件,可以自动关闭 |
1.2、文件写入
# 1. 打开文件
f = open('python.txt', 'w')
# 2.文件写入
f.write('hello world')
# 3. 内容刷新
f.flush()
直接调用write,内容并未真正写入文件,而是会积攒在程序的内存中,称之为缓冲区
当调用flush的时候,内容会真正写入文件
这样做是避免频繁的操作硬盘,导致效率下降(攒一堆,一次性写磁盘)
1.3、文件的追加
# 1. 打开文件,通过a模式打开即可
f = open('python.txt', 'a')
# 2.文件写入
f.write('hello world')
# 3. 内容刷新
f.flush()
a模式,文件不存在会创建文件
a模式,文件存在会在最后,追加写入文件
可以使用”\n”来写出换行符
1.4、文件操作综合案例:文件备份
"""
演示文件操作综合案例:文件备份
"""
# 打开文件得到文件对象,准备读取
fr = open("D:/bill.txt", "r", encoding="UTF-8")
# 打开文件得到文件对象,准备写入
fw = open("D:/bill.txt.bak", "w", encoding="UTF-8")
# for循环读取文件
for line in fr:
line = line.strip()
# 判断内容,将满足的内容写出
if line.split(",")[4] == "测试":
continue # continue进入下一次循环,这一次后面的内容就跳过了
# 将内容写出去
fw.write(line)
# 由于前面对内容进行了strip()的操作,所以要手动的写出换行符
fw.write("\n")
# close2个文件对象
fr.close()
fw.close() # 写出文件调用close()会自动flush()
五、异常处理
1.1、捕获异常
捕获常规异常:
try:
可能发生错误的代码
except:
如果出现异常执行的代码
try:
f = open('linux.txt', 'r')
except:
f = open('linux.txt', 'w')
捕获指定异常:
try:
print(name)
except NameError as e:
print('name变量名称未定义错误')
如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则无法捕获异常。
一般try下方只放一行尝试执行的代码。
捕获多个异常:
当捕获多个异常时,可以把要捕获的异常类型的名字,放到except 后,并使用元组的方式进行书写。
try:
print(1/0)
except (NameError, ZeroDivisionError):
print('ZeroDivision错误...')
异常else:
try:
print(1)
except Exception as e:
print(e)
else:
print('我是else,是没有异常的时候执行的代码')
异常finally:
try:
f = open('test.txt', 'r')
except Exception as e:
f = open('test.txt', 'w')
else:
print('没有异常,真开心')
finally:
f.close()
利用异常具有传递性的特点, 当我们想要保证程序不会因为异常崩溃的时候,
就可以在main函数中设置异常捕获, 由于无论在整个程序哪里发生异常, 最终都
会传递到main函数中, 这样就可以确保所有的异常都会被捕获