02.初识Python
一、认识Python
python
1. 认识Python(了解)
1.1 编程语言?
是用于定义计算机程序的语言,用来向计算机发出指令。
注意:计算机不能直接理解编程语言,只能理解机器语言(二进制,由0和1构成)
1.2 计算机如何理解编程语言?
计算机执行编程语言的转换方式:
1. 编译
2. 解释
解释型语言:使用专门的解释器将代码一行一行转换成机器码并一行一行执行。典型语言:Python
编译型语言:使用专门的编译器将代码一次性编译成机器码执行。典型语言:C、C++
跨平台特性:拿着源文件或者编译后的文件可以到任意平台执行,前提是平台上先配置好所需环境。
1.3 Python语言定义
Python是面向对象的解释型高级编程语言。
二、编写第一个程序
python
2. 编写第一个程序
2.1 两种方式
1. cmd
2. pycharm编辑器(重点)
2.2 cmd中编写程序
1. 打开命令提示符窗口:win+R键 -> 输入cmd -> 回车进入命令提示符窗口
2. 输入python,进入到Python交互模式,它的提示符是>>>。
3. 在交互模式下,直接输入代码print("Hello SixStar"),按回车,就可以立刻得到代码执行结果。
4. 交互模式下输入exit()并回车,就退出了Python交互模式,回到命令行模式。
2.3 pycharm编辑器中编写程序
1. 右键项目名,点击New,选择Python File。
2. 输入文件名(注意:不建议用中文命名),回车或点击OK即可完成新建。
3. 在py文件中编写代码print("Hello SixStar")。
4. 运行代码
三种方式:
1. 右键代码空白处选择Run(推荐使用)
2. 保存或运行代码后下拉框选中要调试的py文件,点击运行图标。
3. 点击工具栏中的Run,然后选择Run...
5. 控制台Console显示结果。
三、Debug
python
3.Debug
3.1 含义
通过工具对代码进行调试,在这里程序员可以查看程序的执行细节和流程。
3.2 使用步骤
1. 打断点
2. Debug调试
3.3 断点调试
3.3.1 概念
在程序自动运行的过程中,在代码某一处打上了断点,当程序跑到你设置的断点位置处,则会中断下来,此时你可以看到之前运行过的所有程序变量。
3.3.2 使用
print(123)
print(123)
print(123)
print(123)
print(123)
print(123)
print(123)
print(123)
设置断点: 鼠标左键点击某一行代码左侧即可设置断点,也可以取消断点。
Debugger面板数据显示在Variables(变量)处,显示的是程序执行过程中的变量及细节,Console面板显示使用print函数输出的数据。
3.3.3 图标及其意义
1. Show Execution Point: 显示执行的断点
2.Step Over: 下一步
注意:蓝色背景的代码是即将执行的代码
3.Run to cursor:直接跳到下一个断点的位置
4.Evaluate Expression:计算表达式
四、注释
python
4. 注释
4.1 作用
用自己熟悉的语言,在程序中对某些代码进行标注说明,能够大大增强程序的可读性。
4.2 注释的分类
4.2.1 单行注释(行注释)
只能注释一行内容。
语法:
# 注释内容
示例:
# 我是注释
print("Hello World") # 输出Hello World
注意:
1. 注释放在前面:为了保证代码的可读性和规范性,#后面建议先添加一个空格,再编写相应的文字说明。
2. 注释放在后面(简单注释):注释和代码之间至少要有两个空格,保证代码的可读性。
4.2.2 多行注释(块注释)
可以注释多行内容,一般用在注释一段代码的情况。
语法:
"""注释内容"""
'''注释内容'''
示例:
"""
第一行注释
第二行注释
第三行注释
"""
'''
注释1
注释2
注释3
'''
# (示例:)
# print(123)
"""
print(123)
print(123)
"""
注意:注释不会被程序执行,只起到说明作用。
4.2.3 什么时候需要使用注释?
1. (注释并不是越多越好,)对于一目了然的代码,不需要添加注释。
2. 对于复杂的操作,应该在操作开始前写上若干行注释。
3. 对于不是一目了然的代码,应在其行尾添加注释(为了提高可读性,注释至少离开代码2个空格)。
# 养成良好的注释习惯非常重要!!!
4.2.4 如何批量注释?
选中代码,按住快捷键Ctrl+/既可以添加注释,也可以取消注释,使用的是单行注释。
# print(123)
# print(123)
# print(123)
五、输出函数
python
5. 输出函数
5.1 语法格式
print(*values, sep=' ', end='\n', file=sys.stdout, flush=False)
注意:print(*values)后面的参数可以省略不写。
5.2 参数
5.2.1 *values
值,表示可以一次输出多个值。输出多个值时,需要用 , 分隔。
print(123) # 数字可以直接输出
print(123, 456, 789) # 输出多个值
print(123456789) # 当成一个值输出
print("bingbing") # 输出一个值
print("冰冰","恣意","麦芽") # 输出多个值
print()
5.2.2 sep
用来间隔多个值,默认值是一个空格。
print("bingbing", "susu", "ziyi") # 默认是空格隔开
print("bingbing", "susu", "ziyi", sep=",") # 值与值之间用,隔开
print("bingbing", "susu", "ziyi", sep="!") # 值与值之间用!隔开
# print("Hello",sep='|',"SixStar") # 语法错误
# 在于参数位置不正确,关键字参数必须跟随在位置参数后面
5.2.3 end
print()
print(123)
用来设定以什么结尾。默认值是换行符 \n,我们可以换成其他任意字符串。
# end里面为空格
print("hello", end=" ")
print("bingbing")
# end里面为逗号,两个print输出的字符串则会用逗号隔开
print("hello", end=",")
print("bingbing")
# end里面为数字,两个print输出的字符串则会用数字隔开
print("hello", end="2")
print("bingbing")
03.变量
一、变量
python
1. 变量
1.1 含义
一个容器,计算机当中的存储空间。
注意:变量可以理解为一个名字或者标签
1.2 作用
在计算机内存中存储数据,我们可以通过变量名提取数据。
1.3 定义变量基本格式
变量名 = 值
注意:=是赋值运算符,左右两边打上空格是为了代码的规范性。
money = 100000000 # 将100000000这个数据存储在money变量中
print(money) # 100000000
# 需求:定义变量存储10000000这个数据
money2 = 10000000
# 需求:将money和money2保存的数据相加,并把结果定义到另一个变量中
total = money + money2 # total也是变量
print(total)
1.4 print('xxx')和print(xxx)的区别
print(num) # NameError: name 'num' is not defined(命名异常,名字未被定义。)
print("num") # num
num = 123
print(num) # 123
# 注意:加上引号,打印引号内的内容,不加引号,会被识别成变量名,而变量使用之前都必须赋值,因为只有在赋值之后才会被创建。
1.5 同一变量可以被反复赋值
num = 1
print(num) # 1
num = 10
print(num) # 10,代码是从上至下运行的
num = 3.6
print(num) # 3.6
# 同一个变量可以被反复赋值,并且可以是不同类型的变量
二、标识符
python
2. 标识符
2.1 含义
标识符就是程序员定义的变量名,函数名。
2.2 标识符规定(必须遵守,没有遵守就直接报错)
1. 只能由数字、字母和下划线(_)组成
示例:user_name、 num1、 _age
错误示例:user!sex、stu id、
注意:
1. 可以用中文命名,但是不推荐,不符合代码的规范性
示例:姓名
2. 标识符外加括号对其本身无影响
示例:(name)
2. 不能以数字开头
错误示例:1num、 2id
3. 不能是关键字
关键字:python中已经使用了的标识符,具有特殊的功能和含义,输入了关键字字体颜色会发生改变。
内置关键字:
False None True and as assert
async await break class continue def
del elif else except finally for
from global if import in is
lambda nonlocal not or pass raise
return try while with yield
错误示例:if、and、with
4. 严格区分大小写
错误示例:
num = 123
print(Num)
# 练习:
# USERID(符合)、 4word(不符合,以数字开头)、book_name(符合)、myclass(符合)、 class(不符合,class是关键字)、user name(不符合,包含特殊字符空格)、 num1(符合)
2.3 变量的命名规范(没有遵守不会报错,是为了代码的规范性)
1.见名知意
示例:username(看到这个变量名就能知道存储的是用户姓名)、password(存储的是密码)
2. 下划线分割法(python中常用的变量名命名规则)
使用小写字母,单词与单词之间使用下划线分开。
示例:user_name、 goods_id(商品编号)
3. 大驼峰命名法
每个单词的首字母大写,其它字母小写。
示例:UserName、GoodsId
4. 小驼峰命名法
第一个单词首字母小写,后面单词首字母大写,其余字母都小写。
示例:userName、goodsId
三、数值类型
python
3. 数值类型
3.1 int(整型) --常用
任意大小的整数。
示例:
num = 1
# 检测数据类型:type()
print(type(num)) # <class 'int'>
3.2 float(浮点型) --常用
小数(带有小数点的数)
示例:
num2 = 1.8
print(type(num2)) # <class 'float'>
height = 1.85
print("身高:", height, "米")
3.3 bool(布尔型) --重点
只有两个固定值:True(真)和False(假),通常用于判断。
value = True
print(type(value)) # <class 'bool'>
注意:
1. 严格区分大小写
print(type(False)) # <class 'bool'>
print(type(false)) # NameError: name 'false' is not defined(命名错误:"false"变量名未被定义)
2. 运算时,布尔值也可以当作整型来对待:True相当于整数1,False相当于整数0。
print(True+False) # 1
print(1+True) # 2
3.4 complex(复数型) --了解
数学概念,包含实部和虚部,一般用于数据计算
固定写法:z = a + bj
a:实部
b:虚部
j:虚数单位
示例:
n1 = 1+2j
print(type(n1)) # <class 'complex'>
n2 = 3+4j
print(n1 + n2) # (4+6j)
注意:j是固定虚数单位,不可更改
n3 = 1+2i
print(n3) # SyntaxError: invalid syntax(语法错误:无效语法)
四、字符串
python
4. str(字符串)
4.1 特点:需要加上引号,可以是单引号,也可以是双引号,包含了多行内容时可以使用三引号。
name = bingbing # NameError: name 'bingbing' is not defined(命名错误:名称"bingbing"未被定义。)
name = 'bingbing'
name = "bingbing"
name = """
我是冰冰
今年十八岁
"""
print(name)
五、格式化输出
python
5. 格式化输出
5.1 含义
按照一定的格式输出内容。
5.2 f'{表达式}'
注意:f格式化字符串是Python 3.6中新增的格式化方法(也就是说只有3.6及以上的版本才有),该方法简单易读。
# 5.2.1 基本用法
sid = 1
name = "bingbing"
age = 18
print(f"我的学号: {sid}, 我的姓名: {name}, 我的年龄: {age}")
# 5.2.2 支持表达式操作
# 数学运算
n1 = 3
n2 = 4
print(f"n1 * n2 = {n1 * n2}") # n1 * n2 = 12
# 5.2.3 小数精度
n1 = 1.23456
print(f"n1保留两位小数: {n1 : .2f}") # n1保留两位小数: 1.23
04.运算符
一、运算符
python
# 1.运算符(掌握)
# 1.1 算术运算符
# 1.1.1 含义
# 完成基本的算术运算使用的符号,用来处理四则运算。
# 1.1.2 运算符
# 1. 加减乘除 +、-、*、/
n1 = 6
n2 = 3
print("n1 + n2 =", n1+n2) # 9
print("n1 - n2 =", n1-n2) # 3
print("n1 * n2 =", n1*n2) # 18
print("n1 / n2 =", n1/n2) # 2.0
# 注意:
# 1. 商一定是浮点数(小数)
# 2. 除数不能为0
# print(3/0) # ZeroDivisionError: division by zero(除零错误,除数不能为0)
# 2. 取整除 //
# 取商的整数部分(向下取整)
# 向下取整:不管四舍五入的规则,只要后面有小数就忽略小数
n1 = 10
n2 = 3
print("n1 // n2 =", n1//n2) # 3
n1 = -10
n2 = 3
print("n1 // n2 =", n1//n2) # -4 (向下取整,画数轴)
# 3. 取余数(取模) %
# 只取余数部分
n1 = 10
n2 = 3
print("n1 % n2 =", n1 % n2) # 1
# 4. 幂 **
# m**n: m的n次方
n1 = 2
n2 = 3
print("n1 ** n2 =", n1**n2) # 8
# 注意:参与运算的数中如果有浮点数,则结果必为浮点数。(/较为特殊,结果必定是浮点数。)
print(1 + 1.0) # 2.0
print(1 - 1.0) # 0.0
print(1 * 1.0) # 1.0
print(1 / 1.0) # 1.0
print(1 // 1.0) # 1.0
print(1 % 1.0) # 0.0
print(1 ** 1.0) # 1.0
# 1.1.3 运算符优先级
# 与数学计算一样:
# - 先乘除后加减
# - 同级运算符从左往右计算
# - 可以用()调整计算的优先级
# 优先级排序: 幂(最高优先级)>乘、除、取余、取整除>加、减
# 1.2 赋值运算符
# 1.2.1 含义
# 主要用于给变量赋值,在使用时,将右侧的值赋给左侧的变量,右侧也可以在进行某些运算后再赋值给左侧的变量。
# 1.2.2 运算符
# 1. = 简单的赋值运算符
# 1.1 直接给变量赋值
n1 = 10
n2 = 20
# 1.2 将一个变量的值赋给另一个变量
n3 = n1
print(n3) # 10
n4 = n2
print(n4) # 20
# 1.3 将运算的值赋给变量
total = n3 + n4
print(total) # 30
# 2. += 加法赋值运算符
# b += a 等效于 b = b + a
n1 = 10
print(n1) # 10
n1 += 1 # n1 = n1 + 1(先运算后赋值) = 11
print(n1) # 11
# 注意:赋值运算符必须连着写,中间不能有空格,否则就会报语法错误,即不符合python的语法规则!!!
# n1 + = 1 # SyntaxError: invalid syntax(语法错误:无效语法)
# print(n1)
# 3. -= 减法赋值运算符
# b -= a 等效于 b = b - a
n1 = 10
print(n1) # 10
n1 -= 1 # n1 = n1 - 1(先运算后赋值) = 9
print(n1) # 9
# 注意:赋值运算符只能针对已经存在的变量赋值。
n += 3 # 等效于n = n + 3,NameError: name 'n' is not defined(命名错误:名称"n"未被定义)
# 纯数字也不能使用,赋值运算符是针对变量存在的
print(10+=3) # 等效于10 = 10 + 3,SyntaxError: invalid syntax(语法错误:无效语法)
二、输入函数
python
# 2. 输入函数(掌握)
# 2.1 含义
# Python中,程序接收用户输入的数据的功能即是输入,通过input函数实现。
# 2.2 语法
# input(prompt=None)
# prompt:提示信息,会在控制台中显示,默认值为None。
input("请输入内容:")
content = input("请输入内容:")
print(content)
# 注意:在python中,input()会把接收到的任意用户输入的数据都当做字符串处理。也就是说,默认输入的就是字符串类型。
info = input("请输入信息:")
print(info, type(info))
三、转义字符
python
# 3. 转义字符(熟练使用)
# 3.1 \t 制表符
# 通常代表4个空格的距离
print("bingbing")
print("\tbingbing")
# 注意:\t能够用于对齐,有自动排版的功能
print('w\t*')
print('ww\t*')
print('www\t*')
print('wwww\t*')
print('wwwww\t*')
print('wwwwww\t*')
print('wwwwwww\t*')
# 3.2 \n 换行符
# 表示将当前位置移到下一行开头
print("Hello 靓仔")
print("Hello\n靓仔")
# 练习:
# 亲爱的周游:
# 祝你 我所希望的一切
# 方式一:
print("亲爱的周游:","\t祝你 我所希望的一切",sep="\n")
# 方式二:
print("亲爱的周游:\n\t祝你 我所希望的一切")
# 3.3 \\ 反斜杠符号
print("\name")
print("\\name") # \\构成转义,表示打印\
print("na\me")
# 3.4 \'和\" 引号
# 表示输出引号
# 需求:打印输出 冰冰说:"永远十八岁"
# 方式一:
print('冰冰说:"永远十八岁"') # 如果字符串中有引号,采用内单外双、外单内双方式。
# 方式二:
print("冰冰说:\"永远十八岁\"")
# 3.5 r 取消转义
# 如果字符串里面有很多字符都会构成转义,就需要加很多\去取消转义,这样很不方便查看,为了简化,python允许使用r''表示引号内部的字符串默认不转义
print("D:\\tools")
print(r"D:\tools")
四、上节课知识点补充
python
# 4. %.1f补充(扩展知识点,了解即可)
# %.1f:数字1表示设置保留1位小数,遵循四舍五入规则
print("%.1f" % 1.05) # 1.1
print("%.1f" % 1.15) # 1.1
print("%.1f" % 1.25) # 1.2
print("%.1f" % 1.35) # 1.4
print("%.1f" % 1.45) # 1.4
print("%.1f" % 1.55) # 1.6
print("%.1f" % 1.65) # 1.6
print("%.1f" % 1.75) # 1.8
print("%.1f" % 1.85) # 1.9
print("%.1f" % 1.95) # 1.9
print(0.1+0.2) # 0.30000000000000004
# 查看精度 ---了解
import decimal
print(decimal.Decimal(1.05)) # 1.1
print(decimal.Decimal(1.15)) # 1.1
print(decimal.Decimal(1.25)) # 1.3(实际:1.2)
print(decimal.Decimal(1.35)) # 1.4
print(decimal.Decimal(1.45)) # 1.4
print(decimal.Decimal(1.55)) # 1.6
print(decimal.Decimal(1.65)) # 1.6
print(decimal.Decimal(1.75)) # 1.8
print(decimal.Decimal(1.85)) # 1.9
print(decimal.Decimal(1.95)) # 1.9
05.if判断
一、if判断
python
# 1. if判断(掌握)
# 1.1 基本格式
# if 要判断的条件:
# 条件成立时需要做的事情
# 需求:成年人才能进网吧打游戏
age = 17
if age >= 18:
print("进网吧,开始打游戏") # 注意冒号和缩进,尽量自动缩进
# 需求:未成年人只能玩泥巴
age = 6
if age < 18:
print("未成年人只能玩泥巴")
# 1.2 作用
# 满足一定条件才会执行代码块,不满足不执行。
二、运算符
python
# 2.运算符
# 2.1 比较运算符(关系运算符)
# 2.1.1 作用
# 用于比较值与值是否相等,或者哪个值大哪个值小,通常用来判断。
# 2.1.2 运算符
# 1. ==比较的是左右两边的值是否相等,相等的话返回True(真),不相等返回False(假)
# 2. !=比较的是左右两边的值是否相等,不相等的话返回True(真),相等返回False(假)
# 注意写法,相等是==,=是赋值运算符,不等是!=,并且必须是英文模式下的符号
a = 3
b = 7
print(a == b) # False
print(a != b) # True
print(a < b) # True
print(a > b) # False
print(a <= b) # True
print(a >= b) # False
# 结合if判断
if a == b:
# 如果相等就输出语句,不相等则不进行任何操作
print("a和b相等") # (没有输出结果,因为a的值与b的值本就不相等)
# 2.2 逻辑运算符
# 2.2.1 作用
# 将多个条件按照逻辑进行连接,变成更复杂的条件。
# 2.2.2 运算符
# 1. and:左右两边都要符合才为真,即所有条件都必须符合才返回为真。
# 需求:两个数都必须为正数,才输出语句。
x = 1
y = 2
if x > 0 and y > 0:
print("x, y都为正数")
# 需求: 只有十八岁的冰冰才是冰冰本人
name = "冰冰"
age = 18
if name == "冰冰" and age == 18:
print("是十八岁的冰冰本人没错了")
# 2. or:左右两边只要一边符合就为真,即只有其中的一个条件符合就返回真。
# 需求: 两个数中有一个数为0就输出语句。
n1 = 5
n2 = 8
if n1 == 0 or n2 == 0:
print("有一个数为0")
# 需求:星期二、星期四、星期六都是有课的
day = input("请输入今天星期几:")
if day == "星期二" or day == "星期四" or day == "星期六":
print("有课哦")
# 3. not:表示相反的结果
print(5 > 8) # False
print(not 5 > 8) # True
# 2.2.3 总结
# (优先级排序:not > and > or) ---不讲
# not:非真即假,非假即真
# and:一假则假,两真则真,两假则假
# or:一真即真,两假即假,两真则真
# 2.2.4 拓展
a = 0
b = 1
c = 2
# and运算符,只要有一个值为0,则结果为0,否则结果为最后一个非0数字
print(a and b) # 0
print(b and a) # 0
print(a and c) # 0
print(c and a) # 0
print(b and c) # 2
print(c and b) # 1
# or运算符,只有所有值为0结果才为0,否则结果为第一个非0数字
print(a or b) # 1
print(a or c) # 2
print(b or c) # 1
三、if-else
python
# 3. if-else结构
# 3.1 基本格式
# if 条件:
# 满足条件做的事
# else:
# 不满足条件做的事
# 需求: 如果是成年人,可以进入娱乐场所;否则无法进入。
age = 16
if age >= 18:
print("可以进入娱乐场所了")
else: # 注意:else后不能添加条件
print("无法入内")
# 需求: 数字比大小
a = 5
b = 8
if a < b:
print("a比b小") # 为真的结果
else:
print('不满足a比b小的条件') # 为假的结果
# 练习:
# 用户登录验证(判断用户名和密码是否匹配成功,登录成功则可以聊天,否则登录失败。)
# 正确的用户名和密码
user_name = 'bingbing'
password = "yy18"
# 用户输入用户名和密码
uname = input("请输入您的用户名:")
upwd = input("请输入您的密码:")
# 判断用户名和密码是否匹配
if uname == user_name and upwd == password:
print("可以和美女聊天了...")
else:
print("登录失败,用户名或密码有误!")
# 3.2 作用
# 条件满足做条件满足该做的事情,即执行if下的代码;条件不满足做条件不满足该做的事情,即执行else下的代码。
# 3.3 三目运算(三元表达式)
# 格式:为真结果 if 判断条件 else 为假的结果
print('a比b小' if a < b else 'a比b大')
# 3.4 if-elif
# if-else是二选一,而if-elif是多选一
# 基本格式:
# if 条件1:
# 事情1
# elif 条件2:
# 事情2
# elif 条件3:
# 事情3
# 注意:这些条件是相关的,前面的条件符合,下面的条件就不会再去进行判断。
# score = 85 # 优秀
# score = 70 # 及格
# score = 45 # 不及格
score = 120
if 85 <= score <= 100:
print("优秀")
elif 75 <= score < 85:
print("良好")
elif 60 <= score < 75:
print("及格")
elif 0 <= score < 60:
print("不及格")
# elif可以写很多个,没有数量限制要求
else: # else可以表示所有条件都不符合的情况
print("成绩无效")
四、if嵌套
python
# 4. if嵌套
# 4.1 含义
# if里面还有if,需要注意缩进,缩进判断层级(是内层if还是外层if)
# 4.2 应用场景
# 在之前条件满足的前提下,再增加额外的判断
# 4.3 格式
# if 条件1:
# 事情1
# if 条件2:
# 事情2
# else:
# 不满足条件的事情
# 注意:外层的if判断,也可以是if-else;内层的if判断,也可以是if-else。
# 需求:火车站安监
# 定义布尔型变量ticket 表示是否有车票
ticket = True # True代表有车票,False代表无车票
# 定义浮点型变量保存体温
temp = 38.5
if ticket: # (== True): # 外层if判断
print("可以进站了-->",end="")
# 安检时,需要检查体温,判断体温是否正常
# 正常人体的腋下体温是36.3°到37.2°
if 36.3 <= temp <= 37.2: # 内层if判断
print("通过安检,终于可以回家了")
else:
print("体温异常,需要隔离")
# 如果没有车票,不能进站
else:
print("没票不能进站")
# 注意:同一个层级不能写两个else
# 4.4 总结
# 1. 根据缩进判断层级
# 2. 根据层级按行执行
# 3. 根据判断条件决定是否符合,符合就执行
# 下节课:循环语句
06.循环语句
一、循环介绍
python
# 1. 循环介绍(熟悉)
# 1.1 含义
# 循环就是重复的去做某一件事情。
# 1.2 分类
# 1.while循环
# 一直重复,直到条件不满足时才结束的循环,又称为条件循环。
# 2.for循环
# 重复一定次数的循环,又称为计次循环。
二、 while循环
python
# 2.while循环(掌握)
# 2.1 含义
# 是通过一个条件来控制是否要继续反复执行循环体中的语句。
# 2.2 基本格式
# 定义初始变量
# while 条件表达式:
# 循环体(重复执行的代码块)
# 改变变量
# 需求:利用while循环输出5遍 "Hello,靓仔!"
i = 1 # 定义一个初始值,记录循环的次数(相当于一个计数器),从第一次开始
while i <= 5: # 当i的值如果满足条件就执行下面的代码
print("Hello,靓仔!")
# 注意:发生死循环的时候,点击左边的红色方框让其停止,不要等到真的卡机,对电脑有损伤
i += 1 # (计算机语言,)等效于i = i + 1 、
# 注意: 如果不改变变量,条件一直满足,就会一直循环下去,一直执行
# 需求2:利用while循环输出8遍这是第n次循环,n是具体的数值
n = 1
while n <= 8:
print(f"当前是第{n}次执行循环") # 格式化输出
print("哈哈哈")
n += 1
# 2.3 死循环
# 规范格式:
# while True:
# 循环体(重复执行的代码块)
# 需求:死循环输出 "完了,芭比q了"
while True:
print("完了,芭比q了")
# 条件只写True,说明一直为真,就会一直执行,从而形成一个死循环
while False:
print("完了,芭比q了")
# 条件只写False,说明为假,不会执行
# 2.4 while循环应用
# 需求:计算1-100的和(数值小一点)
i = 1 # 定义一个初始值,从1开始计算,记录循环次数
s = 0 # 定义一个保存计算结果的变量,最开始计算结果为0,因为一开始没有相加,s和i进行相加
while i <= 100: # 循环100次
# print(i) # 循环打印出1-100
s = s+i # 每次循环的计算结果和i进行相加
i += 1 # 每循环一次i的值加一
# print("计算结果:",s)
# 输出最终计算结果
print("计算结果:", s)
# 2.5 while循环嵌套(难点)
# 2.5.1 含义
# 一个while循环里面还有另外一个循环。
# 2.5.2 基本格式
# while 条件表达式1: # 外层while循环
# 循环体1
# while 条件表达式2: # 内层while循环
# 循环体2
# 注意缩进,缩进决定层级,最好自动缩进
a = 1 # 定义一个变量记录外循环的次数
while a <= 3: # 外循环
print(f"这是第{a}次循环")
b = 1 # 定义一个变量记录内循环的次数
while b <= 5: # 内循环
print(f"内循环{b}")
b += 1 # 改变内循环变量的值
a += 1 # 改变外循环变量的值
# 外循环每执行一次,内循环在条件满足的时候就会一直循环,相当于一个大球里面它有一个自己在转动的小球。
# 需求:九九乘法表
a = 1 # 设置行数的初始值,从第一行开始
while a <= 9: # 一共九行 ---外循环
b = 1 # 设置列数的初始值,从第一列开始
# while b <= 9: # 9列--内循环
while b <= a: # 第n行最多只有n列
# 列数乘以行数
print(f'{b}*{a} = {a * b}', end='\t')
b += 1 # 内循环每循环一次列数加一
print() # 换行,内循环执行完之后需要换行,换到下一行再执行外循环
a += 1 # 外循环每循环一次行数加一
三、for循环
python
# 3.for循环
# 3.1 应用场景
# 通常适用于遍历(依次)取出对象中的元素。一般应用在循环次数已知的情况下。
# 3.2 基本格式
# for 临时变量 in 可迭代对象:
# 循环体(满足条件时执行的代码块)
# 注意冒号和缩进!!!
# 3.3 遍历字符串
st = "长夜漫漫" # 定义一个字符串
for i in st: # 这里的i是临时变量,可以随便写,i是常规写法
print(i)
# st = 1234
# for i in st:
# print(i) # 报错,类型错误,int整型不是可迭代对象
# 重点强调:目前我们所学的数据类型中只有字符串是可迭代对象!!!所以数值类型都不可以在for循环中被依次取值。
st = "12345678910"
for i in st:
# print(i)
print(i, type(i))
# 3.4 range函数
# 3.4.1 含义
# Python内置的函数,用于生成一系列连续的整数,多用于for循环中。
# 3.4.2 格式
# range(start, stop, step)
# start:指定计数的起始值,可以省略,如果省略则从0开始。
# stop: 指定计数的结束值(但不包括该值),不能省略。
# step: 指定步长,即两个数之间的间隔,可以省略,如果省略则表示步长为1。
# 注意:在使用range函数时,如果只有一个参数,那么表示指定的是end;如果是两个参数,则表示的是start和end;只有三个参数都存在时,最后一个才表示步长。
# 需求1:依次打印5个数据
for i in range(5): # 从0开始,5是结束值,但不包含5。可以理解成循环的次数。
print(i)
# 注意:for循环取出的数据会保存在临时变量i中
# 需求2:打印3遍哈哈哈
for i in range(3):
print(i)
print("哈哈哈")
# 需求3:打印1-5这5个数据
for i in range(1, 6): # 从1开始,到6结束,不包括6本身
print(i)
# 注意:range函数遵循包前不包后规则,相当于数学中的[),只包含开始位置,不包含结束位置,如[1,4)代表1<=x<4,[3,5)代表3<=x<5,即不包含结束位置本身。
# 需求4:打印0-10之间间隔为2的数据
for i in range(0, 11, 2): # 从0开始,到11结束,不包含11,步长为2
print(i) # 0 2 4 6 8 10
# 3.5 for循环应用
# 需求:利用for循环计算1-100的和
s = 0 # 定义一个变量保存计算结果
for i in range(1,101): # 从1开始,到100结束,不包含101这个数字
# print(i)
s += i # 等效于s=s+i,每次循环出来的计算结果与i进行相加
#print("结果为:",s) # 写在循环里面就会循环输出计算结果
print("结果为:",s)
四、break和continue
python
# 4.break和continue(难点)
# 注意:都是专门在循环中使用的关键字,一般会结合if语句搭配使用,但不能单独在if语句中使用。
# i = 1
# if i < 3:
# print("哈哈")
# break
# 报错原因:break关键字只能用于循环中。
# 4.1 break
# 作用:某一条件满足时,退出循环。
# 需求1:吃5个苹果,吃完第3个吃饱了,不再继续吃。
i = 1
while i <= 5:
print(f"我在吃第{i}个苹果")
if i == 3:
print("吃撑了不吃了") # 如果i的值为3就跳出当前循环,不再执行了,i=3之后的都不执行
break
i += 1
# 需求2:跑步,原计划跑十圈,跑到第2圈看到女神,终止跑步。
i = 1
while i <= 10:
print(f"跑第{i}圈")
if i == 2:
print("遇到女神了,不跑了")
break
i += 1
# 4.2 continue
# 作用:退出本次循环,下一次循环继续执行
# 需求:吃5个苹果,第3个苹果坏了,吃到了一条虫子,扔掉,继续吃第四个、第五个。
# i = 1
# while i <= 5:
# print(f"我在吃第{i}个苹果")
# if i == 3:
# print("苹果坏了,吃到了一个大虫子")
# continue
# i += 1
i = 1
while i <= 5:
print(f"我在吃第{i}个苹果")
if i == 3:
print(f"吃到了大虫子,不吃第{i}个苹果了")
# 在continue之前一定要修改计数器,否则会陷入死循环
i += 1
continue
i += 1
# 需求2:跑步,原计划跑十圈,跑到第2圈中途,发现女神也要跑步,于是跑回起点等待,制造一次完美邂逅,继续跑第3圈。
i = 1
while i <= 10:
print(f"跑第{i}次")
if i == 2:
print("女神也要跑,第{i}圈不跑了,回原点和女神邂逅")
i += 1
continue
i += 1
for i in range(5):
if i == 3:
break # i的值为3时直接结束循环,不再执行后面的代码
# continue # 跳过i的值为3时候的这一次循环,继续执行下一次循环
print(i)
# 注意:break和continue只针对当前所在的循环有效。也就是说在嵌套循环中,只对最近的一层循环起作用。
# 情况一:在外循环添加break关键字
i = 1
while i < 5: # 外循环
if i == 2:
break # i的值为2时结束外循环,不再执行后面的代码,内循环包含在外循环之中
print(f'这是{i}')
j = 1
while j < 3: # 内循环
print(f"这是第{j}次循环")
j += 1
i += 1
# 情况二:在内循环添加break关键字
i = 1
while i < 5: # 外循环
#if i == 2:
# break # i的值为2时结束外循环,不再执行后面的代码,内循环包含在外循环之中
print(f'这是{i}')
j = 1
while j < 3: # 内循环
if j == 2:
break # j的值为2时结束内循环,继续执行外循环
print(f"这是第{j}次循环")
j += 1
i += 1
06.循环语句
一、循环介绍
python
# 1. 循环介绍(熟悉)
# 1.1 含义
# 循环就是重复的去做某一件事情。
# 1.2 分类
# 1.while循环
# 一直重复,直到条件不满足时才结束的循环,又称为条件循环。
# 2.for循环
# 重复一定次数的循环,又称为计次循环。
二、 while循环
python
# 2.while循环(掌握)
# 2.1 含义
# 是通过一个条件来控制是否要继续反复执行循环体中的语句。
# 2.2 基本格式
# 定义初始变量
# while 条件表达式:
# 循环体(重复执行的代码块)
# 改变变量
# 需求:利用while循环输出5遍 "Hello,靓仔!"
i = 1 # 定义一个初始值,记录循环的次数(相当于一个计数器),从第一次开始
while i <= 5: # 当i的值如果满足条件就执行下面的代码
print("Hello,靓仔!")
# 注意:发生死循环的时候,点击左边的红色方框让其停止,不要等到真的卡机,对电脑有损伤
i += 1 # (计算机语言,)等效于i = i + 1 、
# 注意: 如果不改变变量,条件一直满足,就会一直循环下去,一直执行
# 需求2:利用while循环输出8遍这是第n次循环,n是具体的数值
n = 1
while n <= 8:
print(f"当前是第{n}次执行循环") # 格式化输出
print("哈哈哈")
n += 1
# 2.3 死循环
# 规范格式:
# while True:
# 循环体(重复执行的代码块)
# 需求:死循环输出 "完了,芭比q了"
while True:
print("完了,芭比q了")
# 条件只写True,说明一直为真,就会一直执行,从而形成一个死循环
while False:
print("完了,芭比q了")
# 条件只写False,说明为假,不会执行
# 2.4 while循环应用
# 需求:计算1-100的和(数值小一点)
i = 1 # 定义一个初始值,从1开始计算,记录循环次数
s = 0 # 定义一个保存计算结果的变量,最开始计算结果为0,因为一开始没有相加,s和i进行相加
while i <= 100: # 循环100次
# print(i) # 循环打印出1-100
s = s+i # 每次循环的计算结果和i进行相加
i += 1 # 每循环一次i的值加一
# print("计算结果:",s)
# 输出最终计算结果
print("计算结果:", s)
# 2.5 while循环嵌套(难点)
# 2.5.1 含义
# 一个while循环里面还有另外一个循环。
# 2.5.2 基本格式
# while 条件表达式1: # 外层while循环
# 循环体1
# while 条件表达式2: # 内层while循环
# 循环体2
# 注意缩进,缩进决定层级,最好自动缩进
a = 1 # 定义一个变量记录外循环的次数
while a <= 3: # 外循环
print(f"这是第{a}次循环")
b = 1 # 定义一个变量记录内循环的次数
while b <= 5: # 内循环
print(f"内循环{b}")
b += 1 # 改变内循环变量的值
a += 1 # 改变外循环变量的值
# 外循环每执行一次,内循环在条件满足的时候就会一直循环,相当于一个大球里面它有一个自己在转动的小球。
# 需求:九九乘法表
a = 1 # 设置行数的初始值,从第一行开始
while a <= 9: # 一共九行 ---外循环
b = 1 # 设置列数的初始值,从第一列开始
# while b <= 9: # 9列--内循环
while b <= a: # 第n行最多只有n列
# 列数乘以行数
print(f'{b}*{a} = {a * b}', end='\t')
b += 1 # 内循环每循环一次列数加一
print() # 换行,内循环执行完之后需要换行,换到下一行再执行外循环
a += 1 # 外循环每循环一次行数加一
三、for循环
python
# 3.for循环
# 3.1 应用场景
# 通常适用于遍历(依次)取出对象中的元素。一般应用在循环次数已知的情况下。
# 3.2 基本格式
# for 临时变量 in 可迭代对象:
# 循环体(满足条件时执行的代码块)
# 注意冒号和缩进!!!
# 3.3 遍历字符串
st = "长夜漫漫" # 定义一个字符串
for i in st: # 这里的i是临时变量,可以随便写,i是常规写法
print(i)
# st = 1234
# for i in st:
# print(i) # 报错,类型错误,int整型不是可迭代对象
# 重点强调:目前我们所学的数据类型中只有字符串是可迭代对象!!!所以数值类型都不可以在for循环中被依次取值。
st = "12345678910"
for i in st:
# print(i)
print(i, type(i))
# 3.4 range函数
# 3.4.1 含义
# Python内置的函数,用于生成一系列连续的整数,多用于for循环中。
# 3.4.2 格式
# range(start, stop, step)
# start:指定计数的起始值,可以省略,如果省略则从0开始。
# stop: 指定计数的结束值(但不包括该值),不能省略。
# step: 指定步长,即两个数之间的间隔,可以省略,如果省略则表示步长为1。
# 注意:在使用range函数时,如果只有一个参数,那么表示指定的是end;如果是两个参数,则表示的是start和end;只有三个参数都存在时,最后一个才表示步长。
# 需求1:依次打印5个数据
for i in range(5): # 从0开始,5是结束值,但不包含5。可以理解成循环的次数。
print(i)
# 注意:for循环取出的数据会保存在临时变量i中
# 需求2:打印3遍哈哈哈
for i in range(3):
print(i)
print("哈哈哈")
# 需求3:打印1-5这5个数据
for i in range(1, 6): # 从1开始,到6结束,不包括6本身
print(i)
# 注意:range函数遵循包前不包后规则,相当于数学中的[),只包含开始位置,不包含结束位置,如[1,4)代表1<=x<4,[3,5)代表3<=x<5,即不包含结束位置本身。
# 需求4:打印0-10之间间隔为2的数据
for i in range(0, 11, 2): # 从0开始,到11结束,不包含11,步长为2
print(i) # 0 2 4 6 8 10
# 3.5 for循环应用
# 需求:利用for循环计算1-100的和
s = 0 # 定义一个变量保存计算结果
for i in range(1,101): # 从1开始,到100结束,不包含101这个数字
# print(i)
s += i # 等效于s=s+i,每次循环出来的计算结果与i进行相加
#print("结果为:",s) # 写在循环里面就会循环输出计算结果
print("结果为:",s)
四、break和continue
python
# 4.break和continue(难点)
# 注意:都是专门在循环中使用的关键字,一般会结合if语句搭配使用,但不能单独在if语句中使用。
# i = 1
# if i < 3:
# print("哈哈")
# break
# 报错原因:break关键字只能用于循环中。
# 4.1 break
# 作用:某一条件满足时,退出循环。
# 需求1:吃5个苹果,吃完第3个吃饱了,不再继续吃。
i = 1
while i <= 5:
print(f"我在吃第{i}个苹果")
if i == 3:
print("吃撑了不吃了") # 如果i的值为3就跳出当前循环,不再执行了,i=3之后的都不执行
break
i += 1
# 需求2:跑步,原计划跑十圈,跑到第2圈看到女神,终止跑步。
i = 1
while i <= 10:
print(f"跑第{i}圈")
if i == 2:
print("遇到女神了,不跑了")
break
i += 1
# 4.2 continue
# 作用:退出本次循环,下一次循环继续执行
# 需求:吃5个苹果,第3个苹果坏了,吃到了一条虫子,扔掉,继续吃第四个、第五个。
# i = 1
# while i <= 5:
# print(f"我在吃第{i}个苹果")
# if i == 3:
# print("苹果坏了,吃到了一个大虫子")
# continue
# i += 1
i = 1
while i <= 5:
print(f"我在吃第{i}个苹果")
if i == 3:
print(f"吃到了大虫子,不吃第{i}个苹果了")
# 在continue之前一定要修改计数器,否则会陷入死循环
i += 1
continue
i += 1
# 需求2:跑步,原计划跑十圈,跑到第2圈中途,发现女神也要跑步,于是跑回起点等待,制造一次完美邂逅,继续跑第3圈。
i = 1
while i <= 10:
print(f"跑第{i}次")
if i == 2:
print("女神也要跑,第{i}圈不跑了,回原点和女神邂逅")
i += 1
continue
i += 1
for i in range(5):
if i == 3:
break # i的值为3时直接结束循环,不再执行后面的代码
# continue # 跳过i的值为3时候的这一次循环,继续执行下一次循环
print(i)
# 注意:break和continue只针对当前所在的循环有效。也就是说在嵌套循环中,只对最近的一层循环起作用。
# 情况一:在外循环添加break关键字
i = 1
while i < 5: # 外循环
if i == 2:
break # i的值为2时结束外循环,不再执行后面的代码,内循环包含在外循环之中
print(f'这是{i}')
j = 1
while j < 3: # 内循环
print(f"这是第{j}次循环")
j += 1
i += 1
# 情况二:在内循环添加break关键字
i = 1
while i < 5: # 外循环
#if i == 2:
# break # i的值为2时结束外循环,不再执行后面的代码,内循环包含在外循环之中
print(f'这是{i}')
j = 1
while j < 3: # 内循环
if j == 2:
break # j的值为2时结束内循环,继续执行外循环
print(f"这是第{j}次循环")
j += 1
i += 1
07.字符串
1.字符串编码转换
python
# 1.字符串编码转换(了解)
# 字符--->(翻译过程)--->数字
# 1.1 字符串编码
# 1.1.1 含义
# 字符串编码本质上就是二进制数据与语言文字的一一对应关系。
# 1.1.2 编码格式
# 1. ASCII编码
# 仅对10个数字、26个大小写字母以及一些其他符号进行编码。
# 2.GBK
# GBK和GB2312是我国制定的中文编码标准,使用一个字节表示英文字母,两个字节表示中文字符。
# 3.Unicode(万国码)
# 通常情况下用2个字节表示一个字符,如果是非常偏僻的字符就需要4个字节
# 4.utf-8(常用)
# 国际通用编码,采用一个字节表示英文字符,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。
# 重点强调:Unicode和UTF-8对比
# Unicode:所有字符都是2个字节,这样的好处是字符与数字之间的转换速度更快一些,但是凡事有利也有弊,它的缺点就是占用空间大
# UTF-8: 精准,对不同的字符用不同的长度表示,优点就是节省空间,缺点:字符与数字的转换速度慢,每次都需要计算字符要用多少个字节表示
# 1.2 字符串编码转换
# str是人类理解的,bytes是计算机理解的,两种类型不能拼接在一起使用。
# str和bytes之间可以通过encode()和decode()方法进行转换。
# 1.2.1 encode():编码
# 为str类型提供的方法,用于将str类型转换成bytes类型(二进制数据)。即把字符串编码后告诉计算机,让计算机理解。
# 1.2.2 decode():解码
# 为bytes类型提供的方法,用于将bytes类型的二进制数据转换成str类型。即把bytes二进制数据解码成字符串,让人类能理解。
# 示例1:
a = 'hello'
print(a)
print(type(a)) # str 字符串是以字符为单位进行处理
a1 = a.encode() # 编码
print('编码后: ',a1)
print(type(a1)) # bytes 以字节为单位进行处理的
a2 = a1.decode() # 解码
print('解码后: ', a2)
print(type(a2))
# 注意:对于bytes,目前只要知道它跟字符串类型之间的互相转换
# 示例2:
st = "你今天真好看"
st1 = st.encode('utf-8')
print(st1)
st2 = b'\xe4\xbd\xa0\xe4\xbb\x8a\xe5\xa4\xa9\xe7\x9c\x9f\xe5\xa5\xbd\xe7\x9c\x8b'
st3 = st2.decode('utf-8')
print(st3)
2.字符串常见操作
python
# 2.字符串常见操作(熟练运用)
# 2.1 字符串运算符
# 2.1.1 + 字符串拼接
print(1+1) # 2,整型相加,+是算术运算符
print('1'+'1') # 11,字符串相加,+是字符串拼接
v1 = "美"
v2 = "女"
print(v1+v2) # 美女
# 2.1.2 * 重复输出
# 注意:需要输出多少次*后面就写多少
print("美女" * 3)
print("你好\t" * 3)
# 2.2 成员运算符
# 2.2.1 作用
# 检查字符串中是否包含了某个子字符串(即某个字符或多个字符)。
# 2.2.2 运算符
# 1. in::如果包含的话,返回为True;不包含则返回False
# 2. not in:如果不包含的话,返回为True;包含的话返回False
name = "bingbing"
print("b" in name) # True
print("b" not in name) # False
print("a" in name) # False
print("a" not in name) # True
name2 = "周游"
print("周游" in name2) # True
print("周游" not in name2) # False
print("冰冰" in name2) # False
print("冰冰" not in name2) # True
# 2.3 下标(索引)
# 注意:Python中下标从0开始,就是编号。
# 2.3.1 作用
# 通过下标快速找到对应的数据
# 2.3.2 格式
# 字符串名[下标值]
name = "ziyi"
# 从左往右数,下标从0开始
print(name[0])
print(name[1])
print(name[2])
print(name[4]) # 报错,取值的时候不要超出下标范围
# 从右往左数,下标是从-1开始,-1,-2,-3...
print(name[-1])
print(name[-2])
print(name[-5]) # 报错,超出范围
# 2.4 切片(难点)
# 2.4.1 含义
# 指对操作的对象截取其中一部分的操作
# 2.4.2 语法
# [起始:结束:步长]
# 遵循包前不包后规则:,即从起始位置开始,到结束位的前一位结束(不包含结束位本身)。
name = "sixstar"
print(name[0:3]) # six
print(name[2:5]) # xst
# 从右往左取
print(name[-2:-5]) #
print(name[-5:-2]) # xst
# 步长: 表示选取间隔,不写步长,则默认是1
# 步长的绝对值大小决定切取数据的间隔,正负号决定切取方向。正数表示从左往右取值,负数表示从右往左取值。
name = "sixstar"
print(name[-2:-5:-1]) # ats -1代表从右往左切取
name = '海绵宝宝和派大星星和章鱼哥哥'
# 截取章鱼哥哥:
print(name[-4:-1]) # 章鱼哥
print(name[-4:]) # 章鱼哥哥 下标为-4的位置之后全部切取到
print(name[:]) # 全部切取到
print(name[:-4]) # 下标为-4的位置之前的全部切取到
print(name[::2]) # 海宝和大星章哥
name = 'abcdefghijklmn'
print(name[::2]) #acegikm
print(name[::3]) #adgjm
# 2.5 其他常见操作
# 2.5.1 查找
# 1. find():检测某个子字符串(可以是一个字符也可以是多个字符)是否包含在字符串中,如果在返回这个子串开始的位置下标,否则则返回-1。
# find(子字符串,开始位置下标,结束位置下标)
# 注意:开始和结束位置下标可以省略,表示在整个字符串中查找
name = "bingbing"
print(name.find("i")) # 1 --第一个i的下标为1
print(name.find("bing")) # 0 --检测到第一个bing,b的下标为0
# 返回的是开始的索引/下标值
print(name.find("b",3)) # 4 --从下标3开始找"b",符号和空格也算是一个字符
print(name.find('b',5)) # -1 --超出范围,不包含返回-1
print(name.find('b',3,5)) # 4 --在下标3-5位置范围内查找
# 包前不包后原则
print(name.find('b',3,4))
print(name.find('b',4,6))
# 2.5.2 index():检测某个子字符串是否包含在这个字符串中,如果在返回这个子串开始的位置下标,否则则报异常。
# index(子字符串,开始位置下标,结束位置下标)
# 注意:开始位置和结束位置下标可以省略,表示在整个字符串中查找
name = "我命油我不油天"
print(name.index("命")) # 1
print(name.index('命',2)) # 报错,从下标为2开始找,没有找到
print(name.index('命',1,3)) # 1
# (find没找到返回-1,index没找到返回异常。)
# 同样遵循包前不报后原则
print(name.index('我',1,4)) #3
print(name.index('我',1,3)) #报错,不包含3这个下标
print(name.index('我',3,5)) #3
# 2.5.3 count():返回某个子字符串在字符串中出现的次数,没有则返回0。
# count(子字符串,开始位置下标,结束位置下标)
# 注意:开始和结束位置下标可以省略,表示在整个字符串中查找。
name = "bingbing"
print(name.count('b')) # 2 --b出现2次
print(name.count("a")) # 0 --a没有出现过
print(name.count('b',1)) # 1 --下标为1开始找,只出现过1次
print(name.count('b',1,3)) # 0 --范围内没有出现过
print(name.count('b',0,4)) # 1 --包前不包后,查找范围不包含下标4
print(name.count('b',0,5)) # 2
# 2.6 修改
# 2.6.1 replace():替换
# replace(旧内容,新内容,替换次数)
# 注意:替换次数可以省略,默认全部替换
name3 = "好好学习,天天向上"
print(name3.replace('天','时')) # 好好学习,时时向上
print(name3.replace('天','时',1)) # 好好学习,时天向上
# 2.6.2 split():指定分隔符来切字符串
# split(分隔符,分隔次数)
st = "hello,python"
print(st.split(',')) # ['hello', 'python'] --列表形式返回
# 如果字符串中不包含分割内容,就不进行分割,会作为一个整体。
print(st.split("a")) # ['hello,python']
print(st.split('o')) # ['hell', ',pyth', 'n'] --不设置切割次数,则默认全部分割。
print(st.split('o',1)) # ['hell', ',python'] --指定只切一次
# # 2.6.3 capitalize():第一个字符大写,其他字母都小写
# st = "sixstar"
# print(st.capitalize()) # Sixstar
# # 2.6.4 lower():大写字母转小写
# # 2.6.5 upper():小写字母转为大写
# name = "BingBing"
# print(name.lower())
# print(name.upper())
# 2.7 判断
# 2.7.1 startswith(子字符串, 开始位置下标, 结束位置下标):判断是否以...开头
# 2.7.2 endswith(子串, 开始位置下标, 结束位置下标):判断是否以...结尾
st = "sixstar"
print(st.startswith("s")) # True
print(st.startswith("six")) # True
print(st.startswith("sex")) # False
print(st.startswith("s",0,1)) # True
print(st.startswith('s',3,6)) # True
print(st.startswith('s',2,6)) # False,2-6范围内以x开头
print(st.startswith('x',2,6)) # True
print(st.endswith("r")) # True
print(st.endswith("r",4,6)) # False,包前不包后
print(st.endswith("r",4)) # True,4-最后,以r结尾
# 2.7.3 isupper():判断字符串中所有的字母是否都为大写。是的话就返回True,不是就返回False
# 2.7.4 islower():判断字符串是否由小写字母组成。是的话就返回True,不是就返回False
st = 'sixstar'
print(st.isupper()) # False
print(st.islower()) # True
st1 = 'SIXSTAR'
print(st1.isupper()) # True
print(st1.islower()) # False
st2 = 'sixStar'
print(st2.isupper()) # False
st3 = '123star'
print(st3.isupper()) # False
08.列表&元组
课程内容
python
1. 列表
2. 列表常见操作
3. 元组及其常见操作
1. 列表
python
# 1. 列表(掌握)
# 1.1 定义
# 是处理一组有序项目的数据结构。
# 1.2 格式
# 列表名 = [元素1, 元素2, 元素3, ...]
# 注意:
# 1. 列表的所有元素放在一对中括号[]中,并使用逗号分隔开
# 2. 一个列表中的数据类型可以各不相同
li = [1, 2, 3]
print(li, type(li)) # [1, 2, 3] <class 'list'>
# 1.3 基本使用
# 1.3.1 通过下标快速查找对应元素
li = ['a','b','c','d','e','f']
print(li[2])
# 1.3.2 列表也可以进行切片操作
li = ['a','b','c','d','e','f']
print(li[0::2])
# 1.3.3 列表是可迭代对象,可以for循环遍历取值
for i in li:
print(i)
2. 列表常见操作
python
# 2. 列表常见操作(熟练运用)
# 2.1 添加元素
# 2.1.1 append():在列表末尾追加元素(常用)
li = [1, 2, 3]
li.append(4)
print(li) # [1, 2, 3, 4]
# 2.1.2 extend():分散添加,将另外一个类型中的元素逐一添加。
li = [1, 2, 3]
# li.extend(4) # 报错,整型不是可迭代对象
li.extend('45')
print(li) # [1, 2, 3, '4', '5']
li.extend([6, 7])
print(li) # [1, 2, 3, '4', '5', 6, 7]
# 2.1.3 insert():在指定位置插入元素,指定位置若有元素则原有元素后移。效率没有append高,不推荐使用。
li = [1, 2, 3]
li.insert(3, 4)
print(li)
li.insert(3, 5)
print(li)
# 2.2 修改元素
# 列表名[下标] = 值
li = [1, 2, 3]
li[0] = 0
print(li) # [0, 2, 3]
li[1] = "1"
print(li) # [0, '1', 3]
li[2] = [2]
print(li) # [0, '1', [2]]
# 2.3 查找元素
# 2.3.1 in: 判断指定数据是否存在列表中,如果存在返回为True,不存在则返回False
# 2.3.2 not in:判断指定数据是否存在列表中,如果不存在返回为True,存在则返回False
li = [1, 2, 3]
print(2 in li) # True
print(2 not in li) # False
print(4 in li) # False
print(4 not in li) # True
# 需求:用户输入名字作为昵称,昵称重复则不能使用。
# 定义一个列表,列表中保存已经存在的昵称
name_list = ['bingbing', 'susu', 'ziyi']
# 如果用户输入的用户名被使用就需要重新输入,直到没有重复为止
while True:
# 用户输入昵称
name = input("请输入您要查找的名字:")
# 如果该昵称在列表中存在
if name in name_list:
print(f'您输入的名字{name}已经存在了哦')
# 如果昵称在列表中不存在,即没有和列表中的数据重复
else:
print(f'名字{name}已被您使用')
# 把昵称新增进列表中
name_list.append(name)
# 输出列表
print(name_list)
# 退出当前所在循环
break
# 2.3.3 index():返回指定元素所在位置的下标 ,如果查找的元素不存在则报错。
# 2.3.4 count():统计指定元素在当前列表中出现的次数。
li = [1, 2, 3, 4, 2]
print(li.index(2)) # 1
# print(li.index(5)) # 报错,ValueError: 5 is not in list(值错误:5不在列表中)
print(li.count(2)) # 2,出现2次
print(li.count(5)) # 0,出现0次
# 2.4 删除元素
# 2.4.1 del:根据下标删除,超出下标范围就报错。
li = [1, 2, 3, 4, 5]
del li[4]
print(li) # [1, 2, 3, 4]
# del li[6] # 报错,IndexError: list assignment index out of range(索引错误:列表下标超出范围)
# 删除整个列表
del li
# print(li) # NameError: name 'li' is not defined(命名错误:名字未被定义)
# 2.4.2 remove():根据元素的值进行删除,如果元素不存在则报错。
li = [1, 2, 3, 4, 3]
li.remove(1)
print(li) # [2, 3, 4, 3]
li.remove(3)
print(li) # [2, 4, 3],默认删除最开始出现的指定元素
# li.remove(5) # 报错,ValueError: list.remove(x): x not in list(值错误:元素5不在列表中)
# 2.5 排序
# 2.5.1 sort():将列表按特定顺序重新排列,默认从小到大
li = [2, 5, 3, 4, 1]
li.sort()
print(li) # [1, 2, 3, 4, 5]
# 2.5.2 reverse():倒序,将列表倒置,反过来
li = [2, 5, 3, 4, 1]
li.reverse()
print(li) # [1, 4, 3, 5, 2]
# 需求:将列表按照从大到小的顺序排序
li = [2, 5, 3, 4, 1]
# 先按照从小到大的顺序排序
li.sort()
# 再将列表倒置
li.reverse()
print(li) # [5, 4, 3, 2, 1]
# 2.6 列表推导式
# 2.6.1 [表达式 for 临时变量 in range]:生成指定范围的数值列表
# 需求:生成一个列表,保存1-10这十个数字
li = [] # 定义一个空列表
for i in range(1, 11):
# print(i)
li.append(i) # 把取出的i值放进列表中
print(li) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 使用列表推导式,简化代码
# 方式一:
li = [i for i in range(1, 11)]
print(li) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 方式二(可讲可不讲):
li1 = []
[li1.append(i) for i in range(1,6)]
print(li1)
# 2.6.2 [表达式 for 临时变量 in 列表]:根据列表生成指定需求的列表
li = [1, 2, 3, 4, 5]
# 需求:使用列表推导式生成一个将li全部元素乘以5的新列表
li2 = [(i*5) for i in li]
print(li2) # [5, 10, 15, 20, 25]
# 2.6.3 [表达式 for 变量 in 列表 if 条件]:从列表中选择符合条件的元素组成新的列表
# 需求:将原列表中的所有偶数放进新列表中
li = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
# 定义一个空列表
li2 = []
for i in li:
# 判断是否为偶数:偶数能被2整除,说明余数为0
if i % 2 == 0:
# print(i)
# 追加到li2列表中
li2.append(i)
print(li2) # [2, 4, 6, 8, 10, 12]
# 使用列表推导式,简化代码
li3 = [i for i in li if i % 2 == 0]
print(li3) # [2, 4, 6, 8, 10, 12]
# 2.7 列表嵌套
# 含义:一个列表中又有一个列表
li = ['a','b','c',['d','e','f']] # ['d','e','f']是里面的列表
print(li[2]) # c
print(li[3]) # ['d', 'e', 'f'],取出里面的列表
print(li[3][2]) # f,取出内列表里的元素f
li = ['a','b','c',['d','e',['f','g','h']]]
print(li[3][2][1]) # g,取出内列表的列表的g
3. 元组
python
# 3. 元组(掌握)
# 3.1 格式
# 元组名 = (元素1, 元素2, 元素3...)
# 注意:
# 1. 使用小括号进行数据保存,所有元素包含在小括号内,元素与元素之间用","隔开
# 2. 不同元素也可以是不同的数据类型
tua = (1, 2, 3)
print(tua, type(tua)) # (1, 2, 3) <class 'tuple'>
# 3. 元组只包含一个元素的时候,末尾必须加",",否则返回的是唯一数据的数据类型
tua = () # 定义空元组
print(type(tua)) # <class 'tuple'>
tua = (1)
print(type(tua)) # <class 'int'>
tua = ('bingbing')
print(type(tua)) # <class 'str'>
tua = ('bingbing',)
print(type(tua)) # <class 'tuple'>
# 3.2 元组的常见操作
# 元组只支持查询操作,不支持增删改操作。
li2 = ['a','b','c']
li2[1] ="哈哈哈"
print(li2) # ['a', '哈哈哈', 'c']
tua = ('a','b','c')
print(tua[1]) # b
# print(tua[4]) # 报错,IndexError: tuple index out of range(索引错误:元组下标超出范围)
print(tua[1:]) # ('b', 'c')
# tua[1] = 'a' # 报错,TypeError: 'tuple' object does not support item assignment(类型错误:元组对象不支持修改操作)
# 3.2.1 查询元素
# 1. in:判断某个元素是否存在与元组中,存在就返回True,不存在则返回False。
# 2. not in:判断某个元素是否存在与元组中,不存在就返回True,存在则返回False。
# 3. count():统计指定元素在当前列表中出现的次数。
# 4. index():返回指定元素所在位置的下标 ,如果查找的元素不存在则报错。
# 这四种用法和字符串、列表相同,所以我们就不再继续讲了。
# 5. len():求长度
# 注意:len()也可以在字符串、列表等其他数据类型中使用
tua = (1, 2, 3, 4, 5)
print(len(tua)) # 5,返回的是对象中拥有元素的个数
# 3.3 应用场景
# 3.3.1 函数的参数和返回值
# 3.3.2 格式化输出后面的()本质上就是一个元组
# 方法一:
name = "bingbing"
age = 18
print("%s的年龄是:%d" % (name,age)) # bingbing的年龄是:18
# 方法二:
info = ('bingbing', 18)
print("%s的年龄是:%d" % info) # bingbing的年龄是:18
# 3.3.3 数据不可以被修改,保护数据的安全
09. 字典&集合
课程内容
python
1. 字典
2. 字典常见操作
3. 集合
4. 集合常见操作
1. 字典
python
# 1. 字典(掌握)
# 1.1 格式
# 字典名 = {键1: 值1, 键2: 值2}
# 键值对形式保存,键和值之间必须用:隔开,键值对之间用,隔开
dic = {'name': 'bingbing', 'age': 18}
print(type(dic)) # <class 'dict'>
# 注意:字典中的键具备唯一性,但是值可以重复。
dic2 = {'name': 'bingbing', 'name': 'shanhai'}
print(dic2) # {'name': 'shanhai'} 键名重复则前面的值会被后面的值覆盖
dic3 = {'age1': 18, 'age2': 18}
print(dic3) # {'age1': 18, 'age2': 18}
2. 字典常见操作
python
# 2. 字典常见操作(熟练运用)
# 2.1 查看元素
# 2.1.1 变量名[键名]
dic2 = {'name': '冰冰', 'name2': '山海'}
# print(dic2[2]) # 不可以根据下标,字典中没有下标,查找元素需要根据键名,键名相当于索引
print(dic2['name']) # 冰冰
# print(dic2['tel']) # 报错,键名不存在
# 2.2.2 变量名.get(键名)
dic2 = {'name': 'bingbing', 'name2': 'shanhai'}
print(dic2.get('name2')) # shanhai
print(dic2.get('name3')) # None --键名不存在,返回None
print(dic2.get('name3', '不存在')) # 不存在 --如果不存在(没有这个键名),返回自己设置的默认值
# 2.2 修改元素
# 字典名['键名'] = 值
d = {'name': 'bingbing', 'age': 18}
d['age'] = 20 # 列表通过下标修改,字典通过键名修改
print(d) # {'name': 'bingbing', 'age': 20}
# 2.3 添加元素
# 字典名['键名'] = 值
# 注意:键名存在就是修改,不存在则是新增
d = {'name': '小明','age': 28}
d['remark'] = 1918070991
# print(d)
d['remark'] = "在线征婚"
print(d) # {'name': '小明', 'age': 28, 'remark': '在线征婚'}
# 2.4 删除元素
# 2.4.1 del
# 删除指定键值对,键名不存在就会报错
d = {'name': '小明', 'age': 28}
del d['age']
# del d['remark'] # 没有指定的键就会报错
print("删除后: ", d) # 删除后: {'name': '小明'}
# 删除整个字典
d = {'name': '小明','age': 28}
del d
# print('删除后:' ,d) # 报错
# 2.4.2 clear():清空整个字典里面的东西,但保留了这个字典
d = {'name': '小明','age': 28}
d.clear()
print('删除后',d) # 删除后 {}
# 2.5 其它操作
# 2.5.1 len():求长度
d2 = {'name': 'bingbing', 'age': 18, 'qq': 917848283}
print(len(d2)) # 3,因为字典中有3对键值对
# 2.5.2 keys():返回字典里面包含所有键名
d2 = {'name': 'bingbing', 'age': 18, 'qq': 917848283}
print(d2.keys()) # dict_keys(['name', 'age', 'qq'])
k = d2.keys()
print(type(k))
# 可以for循环遍历取出
d2 = {'name': 'bingbing', 'age': 18, 'qq': 917848283}
for i in d2.keys(): # 只取出键名
print(i)
for i in d2:
print(i)
# 2.5.3 values():返回字典里面包含所有值
d2 = {'name': 'bingbing', 'age': 18, 'qq': 917848283}
print(d2.values()) # dict_values(['bingbing', 18, 917848283])
# for循环取值
for i in d2.values(): # 只取出值名
print(i)
# 2.5.4 items():返回字典里面包含所有键值对(元组形式)的列表
d2 = {'name': 'bingbing', 'age': 18, 'qq': 917848283}
print(d2.items()) # dict_items([('name', 'bingbing'), ('age', 18), ('qq', 917848283)])
# for循环取出键值对
for i in d2.items():
print(i)
# 2.6 字典应用场景
# 使用多个键值对,存储描述一个物体的相关信息
3. 集合
python
# 3. 集合(掌握)
# 3.1 基本格式
# 集合名 = {元素1, 元素2, 元素3...}
s1 = {1, 2, 3}
print(type(s1)) # <class 'set'>
# s1 = {} # 字典和集合都是用的{},用{}定义的是空字典
# print(type(s1)) # <class 'dict'>
# 定义空集合的方式
s1 = set()
print(type(s1)) # <class 'set'>
# 3.2 集合的特点
# 3.2.1 无序
s1 = {'a', 'b', 'c', 'd'}
print(s1)
# 3.2 唯一
s1 = {'a', 'b', 'd', 'c', 'b', 'a'}
print(s1)
# 3.3 确定性
# 注意:集合中的元素必须可hash(散列)
# s = {1, 2, [3, 4]}
# print(s) # TypeError: unhashable type: 'list'(类型错误:不可hash(散列)类型:列表)
# li = [3, 4]
# print(hash(li)) # 报错
# 常见的不可hash类型:列表、字典、集合
# 常见的可hash类型:数值类型、字符串、元组
4. 集合常见操作
python
# 4. 集合常见操作
# 4.1 添加元素
# 4.1.1 add():添加元素,添加的是一个整体
s2 = {1, 2, 3, 4}
print("原集合:", s2) # 原集合: {1, 2, 3, 4}
s2.add(5)
print('添加后', s2) # 添加后 {1, 2, 3, 4, 5}
s2.add(2)
print('添加后', s2) # 添加后 {1, 2, 3, 4, 5},# 因为集合有自动去重功能,所以,当向集合内追加的数据是当前集合已有数据的话,则不进行任何操作。
# s2.add(5,6) # 报错,一次只能添加一个元素
s2.add((5,6)) # 添加一个元组类型的元素
print('添加后', s2) # 添加后 {1, 2, 3, 4, 5, (5, 6)}
# 4.1.2 update():把传入的元素拆分,逐个放入集合中
s2 = {1, 2, 3, 4}
print("原集合:", s2) # 原集合: {1, 2, 3, 4}
# s2.update(567) #报错
s2.update('567')
print('添加后', s2) # 添加后 {1, 2, 3, 4, '5', '6', '7'}
# 4.2 删除元素
# 4.2.1 remove():选择删除的数字如果集合中有就删除,没有就会报错
s2 = {1, 2, 3, 4}
s2.remove(3)
# s2.remove(5) # 报错(集合中没有元素5)
print("删除后:", s2) # 删除后: {1, 2, 4}
# 4.2.2 discard():选择要删除的元素,有就会删除,没有则不会发生改变,不会进行操作
s2 = {1, 2, 3, 4}
print("原列表:", s2) # 原列表: {1, 2, 3, 4}
s2.discard(3)
print('删除后:', s2) # 删除后: {1, 2, 4}
s2.discard(7)
print('删除后:',s2) # 删除后: {1, 2, 4}
# 4.3 交集&并集
# 4.3.1 交集 &
# 表示共有的部分
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a & b) # {3, 4}
a = {1, 2, 3, 4}
b = {5, 6, 7, 8}
print(a & b) # set(),没有共有的部分
# 4.3.2 并集 |
# 表示所有的都放一起,重复的不算
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a | b) # {1, 2, 3, 4, 5, 6}
a = {1, 2, 3, 4}
b = {5, 6, 7, 8}
print(a | b) # {1, 2, 3, 4, 5, 6, 7, 8}
# 4.4 应用场景
# 快速去重
10.函数基础
课程内容
python
1. 函数
2. 返回值
3. 参数
4. 变量作用域
1. 函数
python
# 1. 函数(掌握)
print("从前有座山")
print("山上有座庙")
print("庙里有个老和尚")
print("还有一个小和尚")
print("老和尚在给小和尚讲故事")
print("故事的内容是:")
# 需求1:0-3岁可以重复讲3遍,3-5岁只能讲一遍
age = int(input("请输入孩子的年龄:"))
if 0 <= age < 3:
for i in range(3):
print("从前有座山")
print("山上有座庙")
print("庙里有个老和尚")
print("还有一个小和尚")
print("老和尚在给小和尚讲故事")
print("故事的内容是:")
elif 3 < age < 5:
print("从前有座山")
print("山上有座庙")
print("庙里有个老和尚")
print("还有一个小和尚")
print("老和尚在给小和尚讲故事")
print("故事的内容是:")
# 缺点:代码冗余,可读性差,可维护性差,改起来很麻烦,全部都要改
# 1.1 含义
# 函数就是一堆可以完成某项工作的代码,在需要的时候再去调用这一堆代码,可以反复使用。
# 1.2 作用
# 1. 增加代码的重复使用率
# 2. 减少了代码量
# 1.3 基本格式
# 1.3.1 定义函数
# def 函数名():
# 函数体
# 注意: 函数名要符合标识符规定,并且最好是见名知意,方便后续的调用。
# 2.调用函数:
# 函数名()
# 需求2:利用函数将需求1代码进行优化
age = int(input("请输入孩子的年龄:"))
def tell_story():
print("从前有座山")
print("山上有座庙")
print("庙里有个老和尚")
print("还有一个小和尚")
print("老和尚在给小和尚讲故事")
print("故事的内容是:")
if 0 <= age <= 3:
for i in range(3):
tell_story() # 调用函数
elif 3 < age <= 5:
tell_story()
# 需求3:定义一个欢迎新学员的函数,并调用它。
def say_hello():
print("你好呀")
print("我是主讲老师冰冰")
print("以后有什么问题可以咨询我")
# 调用函数
say_hello()
say_hello()
# 注意:不能将函数定义放在函数调用之前,因为在调用函数之前必须要保证函数已经存在。
2. 返回值
python
# 2. 返回值(掌握)
# 2.1 含义
# 函数执行结束后,最后给调用者的一个结果。
# 2.2 语法
# return 返回值
# 2.3 作用
# 2.3.1 给函数的调用者返回结果。
def func():
return 123
func()
print(func()) # 123
# 可以对返回值进行后续处理
print(func()+123) # 246
# 2.3.2 函数中遇到return,表示此函数结束,不继续往下执行。
def func():
return 123
print(456) # 不执行!
print(func()) # 123
# 思考:如果有多个返回值如何编写代码?
def func():
return 123, 456 # 多个返回值,以元组的形式返回给调用者
print(func()) # (123, 456)
print(type(func())) # <class 'tuple'>
# 注意:并不是所有的函数都必须要有返回值。当函数中没有返回值时,返回值为None,即空值。
def func():
print(123)
print(func()) # 123\nNone
# print(func()+1) # 报错
# 2.4 返回值的三种情况总结
# 1. 如果一个返回值也没有,返回的结果是None
# 2. 如果有一个值,把值返回给调用者
# 3. 如果有多个值,以元组的形式返回给调用者
3. 参数
python
# 3. 参数(掌握)
# 需求1:定义一个函数,返回两个值相加的结果。
def add():
a = 1
b = 2
return a+b
print(add()) # 3
# 弊端:计算的值固定化了、
# 3.1 形参&实参
# 3.1.1 形参(形式上的参数)是函数定义时,小括号里面变量。
# 3.1.2 实参(实际上的参数)是函数调用时,小括号里面具体的值。
def add(a,b): # a和b是形参
return a+b
print(add(5, 6)) # 11,5和6是实参
# 函数的传参就是将实参交给形参的过程,如a = 5, b = 6。
# 3.2 必备参数(位置参数)
# 3.2.1 含义
# 传递和定义参数的顺序及个数必须一致。
# 3.2.2 格式
# # 定义函数
# def func(a, b):
# 代码
# # 调用函数
# func(a, b)
def print_value(a, b):
print("a:", a)
print("b:", b)
print_value(1, 2)
print_value(2, 1)
# print_value(1, 2, 3) # 报错
# print_value(1) # 报错
# 3.3 缺省参数(默认参数)
# 3.3.1 含义
# 为参数提供默认值,调用函数时可不传该默认参数的值。
# 3.3.2 格式
# def funa(a=12):
# 代码
# funa()
# funa(18)
def introduce(name, age=18): # name是必备参数,age是默认参数
print(f'你好呀,我是{name},今年{age}岁了')
introduce("bingbing") # 你好呀,我是bingbing,今年18岁了
introduce("bingbing", 19) # 你好呀,我是bingbing,今年19岁了
# 注意:非默认参数要放到默认参数的前面,不然会报错语法错误。可以有多个默认参数。
# def say_hello(age=18, name):
# print(f'你好呀,我是{name},今年{age}了')
# say_hello(15, 'bingbing') # 报错,语法错误,默认参数必须放在非默认参数后面
# 3.4 可变参数
# 3.4.1 含义
# 传入的值的数量是可以改变的,可以传入多个,也可以不传。
# 3.4.2 格式
# def funa(*args):
# 代码
# funa()
# funa(值1, 值2...)
# print()函数中的*values表示可以传一个值,可以传多个值,甚至还可以不传,就是*values表示可变参数
# print()
# print(123)
# print(123, 456)
# 注意:args:普通形参名,*才表示有特殊意义,约定使用args,可以改成其他的。
# def say_hello(args):
# print(args)
# say_hello()
# 不加*是必备函数
def say_hello(*args):
print(args)
print(type(args)) # <class 'tuple'>,可变参数以元组形式接收
say_hello() # ()
say_hello('hello', '你好') # ('hello', '你好')
# 3.5 关键字参数
# 3.5.1 含义
# 属于可变参数,通过**kwargs接收关键字参数然后将其转换成一个字典赋值给kwargs这个形参。
# 3.5.2 格式
# def funa(**kwargs):
# 代码
# funa()
# funa(变量1=值1,变量2=值2...)
# 注意:kwargs:普通形参名,约定使用kwargs,可以改成其他的,**具有特殊意义。
def say_hello(**kwargs):
print(kwargs)
print(type(kwargs)) # <class 'dict'>,关键字参数以字典形式接收
say_hello() # {}
# say_hello('bingbing', 18) # 报错
say_hello(name='bingbing',age='18',sex='女') # {'name': 'bingbing', 'age': '18', 'sex': '女'}
# 3.5.3 作用
# 扩展函数的功能
4. 变量作用域
python
# 4.变量作用域(掌握)
# 4.1 含义
# 指变量生效的范围。
# 4.2 分类
# 4.2.1 局部变量
# 4.2.2 全局变量
# 4.3 局部变量
# 4.3.1 含义
# 函数内部定义的变量,仅在函数内部有效。
def testA():
a = 100 # 局部变量
print("a:", a)
testA()
# print("testA中a的值:", a) # 报错(命名异常,a没有被定义)
# def testB():
# print("a:", a)
# testB() # 报错
# 4.3.2 作用
# 在函数体内部,临时保存数据,当函数调用完成后,则在内存中释放局部变量。
def testB():
a = 100 # 局部变量
# a = 120
print("a:", a) # 100
testB()
# 4.4 全局变量
# 4.4.1 含义
# 函数外部定义的变量,在函数体内、外都能生效。
a = 100 # 全局变量
def testA():
print("testA中a的值:", a) # 访问全局变量a,并打印变量a存储的数据
def testB():
print("testB中a的值:", a) # 访问全局变量a,并打印变量a存储的数据
testA() # 100
testB() # 100
# 4.5 全局变量和局部变量命名相同
a = 100 # 全局变量
def testA():
print("testA中a的值:", a)
def testB():
a = 120
print("testB中a的值:", a)
print("调用函数前的全局变量a的值: ", a) # 100
testA() # 100
testB() # 120
print("调用函数后的全局变量a的值: ", a) # 100
# 4.6 global
# 4.6.1 作用
# 1. 修改全局变量的值
# 2. 将局部变量声明为全局变量
# 4.6.2 语法
# global 变量名
a = 100 # 全局变量
def testA():
print("testA中a的值:", a)
def testB():
# global a = 120 # 错误写法 无效语法
global a # 声明全局变量
a = 120
print('testB中a的值:', a)
testA()
testB()
print("函数外的a:", a)
# 示例2:
def study():
global name
name = "sixstar"
print(name)
study()
print(name) # 函数外打印的name,是全局变量名
# 成为全局变量,可以在另一个函数中被调用了。
def work():
print(name)
work()
# 总结: global关键字可以对全局变量进行修改,也可以在局部作用域中声明一个全局变量。
# 思考:如果需要声明多个全局变量怎么办?
def study():
global name, course # 可以使用global一次性对多个全局变量进行声明
name = "sixstar"
course = "python基础"
print(name,course)
study()
# print(name) # 函数外打印的name,是全局变量名
def work():
print(course)
work()
# 4.7 nonlocal(了解)
# 4.7.1 作用
# 将变量声明为外层变量(外层函数的局部变量,而且不能是全局变量)
# 注意:用来声明外层的局部变量,只能在嵌套函数中使用,在外部函数先进行声明,在内部函数进行nonlocal声明
a = 10 # 全局变量
def outer(): # 外部函数
a = 5 # outer函数定义的局部变量
def inner(): # 内部函数
print('inner函数中的a值:', a) # inner函数中的a值: 5
inner() # 调用inner函数
print('outer函数中的a值:', a) # outer函数中的a值: 5
outer() # 调用outer函数
# 函数内部如果要使用变量,会先从函数内部找,有的话直接使用;没有会到函数外面找。
a = 10 # 全局变量
def outer(): # 外部函数
a = 5 # outer函数定义的局部变量
def inner(): # 内部函数
nonlocal a # 使用nonlocal声明,对上一级进行修改。
a = 20
print('inner函数中的a值:', a) # inner函数中的a值: 20
inner() # 调用inner函数
print('outer函数中的a值:', a) # outer函数中的a值: 20
outer() # 调用outer函数
09.类型转换&深浅拷贝
课程内容
python
1. 类型转换
2. 深浅拷贝
3. 可变对象
4. 可变对象
1. 简单回顾数据类型
python
1. 简单回顾数据类型
1) 数值类型:int整型、float浮点型、bool布尔型、complex复数型 无下标 -> 不可切片 -> 不可for循环遍历
2) str 字符串:使用引号包含的数据(单/双引号包含,多行的时候也可以使用三引号),是由一个个字符(元素)组成 有下标 -> 可切片 -> 可for循环遍历 -> 可迭代对象
下标/索引:从左往右从0开始,从右往左-1开始
切片:[起始:结束:步长] 步长绝对值大小决定间隔,正负号决定切取方向
3) list 列表:[]定义 有下标(有序) -> 可切片 -> 可for循环遍历 -> 可迭代对象
4) tuple 元组:()定义 有下标(有序) -> 可切片 -> 可for循环遍历 -> 可迭代对象
注意:
① 如果只有一个元素,末尾必须添加,
② 只支持查询操作,不支持增删改操作
5) dict 字典:{}定义,以键值对形式存储数据,无下标 -> 不可切片,但是键名(唯一性)相当于下标;可for循环遍历 -> 可迭代对象
6) set 集合:{}定义,无序 -> 无下标 -> 不可切片;唯一 -> 自动去重 可for循环遍历 -> 可迭代对象
2. 类型转换
python
# 2. 类型转换(掌握)
# 2.1 int():转换为一个整数,只能转换由纯数字组成的字符串
# num = input("请输入一个数字:") # input默认是字符串
num = int(input("请输入一个数字:"))
print(num, type(num))
if num == 123: # 必须严格控制缩进
print("输入正确")
print(int(1.2)) # 1
print(int(1.8)) # 1
print(int(-1.2)) # -1
print(int(-1.8)) # -1
# 浮点型强转整型会去掉小数点及后面的数值,只保留整数部分
print(int('123')) # 123
# print(int('bingbing')) # 报错
# print(int('10+10')) # 报错
# 如果字符串中有数字和正负号(+/-)以外的字符就会报错
print(int('+10')) # 10
print(int('-10')) # -10
# +/-写在前面表示正负号,不可以写在后面
# print(int('10+')) # 报错
# 2.2 float():转换为浮点数
print(float(11)) # 整型转换为float时,会自动添加因为小数
print(float('-11')) # 11.0
print(float('+11.345')) # 11.345
# print(float('23-')) # 报错
# 2.3 str():转换为字符串
# 注意:任意类型都可以转换成字符串类型
print(type(n)) # <class 'int'>
n2 = str(n)
print(n2, type(n2)) # 100 <class 'str'>
# str1 = str(-1.8)
str1 = str(-1.80) # float转换str会去除末位的0的小数部分
print(str1, type(str1)) # -1.8 <class 'str'>
# 2.4 eval():用来执行一个字符串表达式,并返回表达式的值
print(10+10) # 20
print('10'+'10') # 1010
print(eval('10+10')) # 20 执行运算,并返回运算值
# print(eval("10+'10'")) # 报错,整型和字符串不可以相加
# st = '[1, 2, 3]'
st = '(1, 2, 3)'
print(type(st)) # str
li = eval(st)
print(li, type(li)) # list
# 2.5 dict():转换成字典类型 ---扩展
d = dict(name='bingbing', age=18, tel=12345) # 传入关键字
print(d, type(d)) # {'name': 'bingbing', 'age': 18, 'tel': 12345} <class 'dict'>
# list->dict
# li = [1, 2, 3]
# d = dict(li) # 报错,必须以键值对方式进行存储。
li = [('name', 'bingbing'), ('age', 18)] # 列表里面的元素需要是元组形式
d = dict(li)
print(d, type(d)) # {'name': 'bingbing', 'age': 18} <class 'dict'>
3. 深浅拷贝
python
# 3. 深浅拷贝(熟练运用)
# 3.1 赋值(数据完全共享)
# 赋值会随着原对象一起变化,原对象改变,赋值过的对象也跟着一起改变
li = [1, 2, 3, 4, 5]
# print(li)
li2 = li # 将li直接赋值给li2
print("li:", li) # li: [1, 2, 3, 4, 5]
print("li2:", li2) # li2: [1, 2, 3, 4, 5]
# 给li列表新增元素
li.append(6)
print("修改后的li:", li) # 修改后的li: [1, 2, 3, 4, 5, 6]
print("修改后的li2:", li2) # 修改后的li2: [1, 2, 3, 4, 5, 6]
# 对列表的增加操作,li和li2都发生了变化,因为li赋值给了li2
# 赋值:赋值等于完全共享资源,一个值的改变会完全被另一个值共享。
# 3.2 浅拷贝(数据半共享)
# 会创建新对象,拷贝第一层的数据,嵌套层会指向原来的内存地址。
import copy # 导入copy模块
li = [1, 2, 3, [4, 5, 6]] # 定义一个嵌套列表,一个列表里面还有一个列表
li2 = copy.copy(li) # 浅拷贝
print("li原列表:", li) # li原列表: [1, 2, 3, [4, 5, 6]]
print("li2原列表:", li2) # li2原列表: [1, 2, 3, [4, 5, 6]]
# 查看内存地址 id()查看变量的内存地址
print("li内存地址:", id(li)) # li内存地址: 1622030701576
print("li2内存地址:", id(li2)) # li2内存地址: 1622317333896
# li和li2内存地址不一样,它们都是独立的对象
li.append(8)
print("这是li:", li) # 这是li: [1, 2, 3, [4, 5, 6], 8]
print("这是li2", li2) # 这是li2 [1, 2, 3, [4, 5, 6]]
# 在嵌套列表添加元素
li[3].append(7)
print("这是li:", li) # 这是li: [1, 2, 3, [4, 5, 6, 7], 8]
print("这是li2", li2) # 这是li2 [1, 2, 3, [4, 5, 6, 7]]
# 两个嵌套列表里面都发生了改变
# 因为li和li2里面的嵌套列表内存地址相同
print(id(li[3])) # 1622030701064
print(id(li2[3])) # 1622030701064
# 外层的内存地址不同,但是内层的内存地址相同。
# 注意:大多数情况下,编写程序时都是使用浅拷贝,除非有特定的需求。
# 优点:拷贝速度快,占用空间少,拷贝效率高。
# 3.3 深拷贝(数据完全不共享)
# 外层的对象和内部的元素都拷贝(赋值)了一遍。
import copy # 导入copy模块
li = [1, 2, 3, [4, 5, 6]] # 定义一个嵌套列表,一个列表里面还有一个列表
li2 = copy.deepcopy(li) # 深拷贝
print("li原列表:", li) # li原列表: [1, 2, 3, [4, 5, 6]]
print("li2原列表:", li2) # li2原列表: [1, 2, 3, [4, 5, 6]]
# 查看内存地址 id()查看变量的内存地址
print("li内存地址:", id(li)) # li内存地址: 2568365626376
print("li2内存地址:", id(li2)) # li2内存地址: 2566514956232
# li和li2内存地址不一样,它们都是独立的对象
li.append(8)
print("这是li:", li) # 这是li: [1, 2, 3, [4, 5, 6], 8]
print("这是li2", li2) # 这是li2 [1, 2, 3, [4, 5, 6]]
# 在嵌套列表添加元素
li[3].append(7)
print("这是li:", li) # 这是li: [1, 2, 3, [4, 5, 6, 7], 8]
print("这是li2", li2) # 这是li2 [1, 2, 3, [4, 5, 6]]
# li和li2是一个独立的对象,两者互不干扰
# 查看嵌套列表内存地址
print(id(li[3])) # 2568365625864
print(id(li2[3])) # 2568370592264
# 深拷贝数据变化只会影响自己本身,跟原来的对象没有关联了
4. 可变类型
python
# 4. 可变类型(熟悉)
# 4.1 含义
# 存储空间保存的数据允许被修改,这种数据就是可变类型
# 4.2 常见的可变类型
# 1. 列表 list
# 2. 字典 dict
# 3. 集合 set
li = ['上九天揽月', '下五洋捉鳖', '海底月是天上月']
print('li的原内存地址:', id(li)) # li的原内存地址: 1387151315464
li.append('眼前人是心上人')
print(li) # ['上九天揽月', '下五洋捉鳖', '海底月是天上月', '眼前人是心上人']
print('li的现内存地址:', id(li)) # li的现内存地址: 1387151315464
dic = {'name': '洗衣', 'name1': '做饭', 'name2': '带娃'}
print(dic) # {'name': '洗衣', 'name1': '做饭', 'name2': '带娃'}
print("dic的原内存地址:", id(dic)) # dic的原内存地址: 1798342323880
dic['name'] = '拖地'
print(dic) # {'name': '拖地', 'name1': '做饭', 'name2': '带娃'}
print("dic的现内存地址:", id(dic)) # dic的现内存地址: 1798342323880
# 总结:对于可变类型,变量对应的值可以修改,但是内存地址保持不变
5. 不可变类型
python
# 5. 不可变类型(熟悉)
# 5.1 含义
# 存储空间保存的数据不允许被修改,这种数据就是不可变类型。
# 5.2 常见的不可变类型
# 1. 数值类型: int, bool, float, complex
# 2. 字符串: str
# 3. 元组: tuple
n = 10 # 整型
print("原地址", id(n)) # 原地址 140713577446752
n = 15 # 修改n会生成新的值,重新赋值给变量n
print(n) # 15
print("现地址", id(n)) # 现地址 140713577446912
# 内存地址不一样:
# 修改n会生成新的值,重新赋值给变量n
st = 'hello'
print("原地址:", id(st)) # 原地址: 2181801788208
st = 'hello python'
print("现地址:", id(st)) # 现地址: 2181804213424
# 总结:对于不可变类型,变量对应的值不能被修改,如果修改就会生成一个新的值从而分配新的内存空间。
# 注意:深浅拷贝只针对可变对象,不可变对象类型没有拷贝的说法。
正课11. 异常&模块&包
课程内容
python
1. 异常
2. 模块
3. 包
1. 异常
python
# 1. 异常(掌握)
# 1.1 含义
# 异常是程序执行过程中出现的非正常流程现象。
# 1.2 常见异常种类
# 参考ppt。
# print(name)
# Traceback---异常的追踪信息,可以追溯到程序异常的具体位置
# xxxxError---异常类型,后面包含异常具体信息
# 方式一:根据异常Traceback找到出错点,进行分析改正
print('name')
name = "bingbing"
print(name)
# 方式二:
# 1.3 异常处理(捕获异常)
# 1.3.1 语法格式一
# try:
# 可能会引发异常的代码
# except 异常类型: # 异常类型可以省略
# 如果检测到异常要执行的代码
try:
print(name)
except:
print("这个是错误的哦!")
# 注意:一般try下面只放一行尝试执行的代码
try:
print(name)
except NameError: # 只捕获命名错误
# except TypeError: # 只捕获类型错误
print("这个是错误的哦!")
try:
print(name)
except (TypeError, NameError):
print("这个是错误的哦!")
try:
print(name)
except Exception: # Exception万能异常,可以捕获任意异常
print("这个是错误的哦!")
# 捕获异常具体描述信息
try:
print(name)
except Exception as e:
print("异常信息:", e)
try:
print('name')
except:
print("这个是错误的哦!")
# 注意:try里面的代码检测出异常时,except才会被执行,如果try里面的代码没有被检测出异常,except下面的代码不会被程序执行。
# 1.3.2 语法格式二
# try:
# 可能会引发异常的代码
# except:
# 如果检测到异常要执行的代码
# else:
# 没有检测到异常要执行的代码
try:
print(name)
except Exception:
print("这个是错误的哦!")
else:
print("这里是else的代码,没有异常就会执行。")
# 这个是错误的哦!
try:
print("name")
except Exception:
print("这个是错误的哦!")
else:
print("这里是else的代码,没有异常就会执行。")
# name
# 这里是else的代码,没有异常就会执行。
# 1.3.3 语法格式三
# try:
# 可能会引发异常的代码
# except:
# 如果检测到异常要执行的代码
# else:
# 没有检测到异常要执行的代码
# finally:
# 无论是否检测到异常,都会执行的代码
# 注意:可以单独使用try...finally...,也可以配合except等使用。
try:
print(name)
except Exception:
print("这个是错误的哦!")
else:
print("没有异常,真开心呀。")
finally:
print("不管怎样我都会执行哦")
# 这个是错误的哦!
# 不管怎样我都会执行哦
try:
print("name")
except Exception:
print("这个是错误的哦!")
else:
print("没有异常,真开心呀。")
finally:
print("不管怎样我都会执行哦")
# name
# 没有异常,真开心呀。
# 不管怎样我都会执行哦
# 1.4 使用raise语句抛出异常
# 语法:
# 1.创建一个异常('xxx')对象,xxx---异常提示信息
# 2.raise抛出这个异常对象
# 需求1:自定义一个异常,然后主动抛出
# e = Exception("冰冰主动抛出了一个异常")
# raise e
# 需求2:自定义一个密码不足八位数的异常
# raise Exception("密码不足8位")
# 需求3:密码长度不足8位,就报异常(用户输入密码,如果输入的长度不足8位,就主动抛出自定义异常,并捕获该异常。)
def login():
pwd = input("请输入您要输入的密码:")
if len(pwd) >= 8:
return "密码输入成功"
e = Exception("长度不足8位,密码输入失败")
raise e
# print(login())
try:
print(login())
except Exception as e:
print(e)
2. 模块
python
# 2.模块(掌握)
# 2.1 含义
# 一个py文件就是一个模块。
# 2.2 分类
# 2.2.1 内置模块
# 2.2.2 第三方模块
# 使用之前需要下载安装,通过如下指令实现:
# pip install 模块名
# 2.2.3 自定义模块
# 2.3 导入模块
# 2.3.1 作用
# 可以在程序任意位置使用,一般建议写在文件开头(py文件开头先导入模块),同一个模块只需要导入一次。
# 2.3.2 实现方式
# 1. import 模块名 [as 别名]:导入模块所有内容
# (新建test.py文件,内容如下:)
name = "bingbing"
def func():
print("这是test模块中的func函数。")
# 需求1:导入一个名称为test的模块,并执行该模块中的func函数。
import test # 导入模块
test.func() # 调用test模块中的func函数
import test as t # 导入test模块并设置别名为t
t.func()
import test, py01, py02 # 一次导入多个模块(不推荐使用)
# 2. from 模块名 import 功能(函数,变量,类):从模块中导入指定部分
# 需求2:导入test的模块中的func函数并调用。
from test import func # 导入test模块中的func函数
func() # 调用func函数
# print(name) # 报错,name变量未被定义
from test import func, name # 导入test模块中的func函数,变量name
func() # 调用func函数
print(name) # 访问name变量
from test import * # 导入test模块中的全部定义
func()
print(name)
# 注意:在使用from...import...语句导入时,需要保证模块中内容不能重名,否则将出现冲突,后导入的同名变量、函数或者类会覆盖先导入的,这时需要使用import语句进行导入。
name = "ziyi"
def func():
print("这是test2模块中的func函数。")
# py12.py:
from test import *
from test2 import *
print(name) # ziyi
func() # 这是test2模块中的func函数。
# 2.4 以主程序的形式执行
# test.py:
name = "bingbing"
def func():
print("这是test模块中的func函数。")
print("我的名字:", name)
print("========调用func函数前========")
func()
print("========调用func函数后========")
# py12.py:
import test # 导入test模块
print("name:", test.name)
# 运行结果:
# 我的名字: bingbing
# ========调用func函数前========
# 这是test模块中的func函数。
# ========调用func函数后========
# name: bingbing
# 测试代码不想被其他模块运行,可以通过if __name__ == "__main__"实现。
# test.py:
name = "bingbing"
def func():
print("这是test模块中的func函数。")
if __name__ == "__main__":
print("我的名字:", name)
print("========调用func函数前========")
func()
print("========调用func函数后========")
# 当模块自己执行自己,__name__的值为"__main__";当模块被其他模块导入时,__name__的值为模块名。
# pytest01.py:
print(__name__) # __main__,自己执行自己,输出__main__
# py12.py:
import pytest01 # pytest01,被当作模块导入,输出模块名称
3. 包
python
# 3. 包(掌握)
# 3.1 含义
# 包就是项目结构中的文件夹/目录。
# 与普通文件夹区别:包含有__init __.py文件
# 3.2 作用
# 1. 规范代码,使结构更清晰
# 2. 有效避免模块名重名引发冲突问题
# 3.3 包的创建和使用
# 3.3.1 创建包
# 操作步骤:右键点击项目名->New->Python Package->输入包名->OK(或直接按回车键)
# 注意:在__init__.py文件中编写的代码,在导入包时会自动执行。
# __init__.py:
print("我是__init__.py文件")
# 3.3.2 使用包(导包)
# 1. import 包名(.模块名)
# py13.py:
import pack01 # 导入pack01包
# 不建议在__init__.py文件中编写过多代码,尽量保证内容简单。
# py01.py:
name = "bingbing"
# py02.py:
age = 18
# py13.py:
import pack01.py01 # 导入pack01包下的py01模块
print(pack01.py01.name) # bingbing
# print(pack01.py02.age) # 报错,没有导入py02模块
# 2. from 包名 import 模块名:导入指定模块
# py13.py:
from pack01 import py01 # 导入pack01包下的py01模块
print(py01.name) # bingbing
# py13.py:
from pack01 import * # 导入pack01包下所有内容
# print(name) # 报错
# print(py01.name) # 报错
# print(pack01.py01.name) # 报错
# __init__.py的主要作用: 导入这个包内的其他模块
# 导包使用from 包名 import *时,必须在__init__.py文件中添加__all__ = [],控制允许导入的模块列表。
# 3.4 __all__变量
# 一个列表,可以控制要导入的内容(模块、函数、类等)
# 模块中有__all__,被from 模块 import *导入时,只能导入列表中的元素。
# 包下的__init__.py中有__all__,被from 包名 import *导入时,只能导入列表中的模块。
# __init__.py:
__all__ = ['py01'] # 使用from 包名 import *导入时只导入py01模块
# py13.py:
from pack01 import *
print(py01.name)
# print(py02.age) # 报错,在__init__.py中只定义了py01模块
12.面向对象基础
一、面向对象
python
# 1. 面向对象(熟悉)
# 1.1 含义
# 是一种抽象化的编程思想,是当前软件开发领域的主流技术。
# 1.2 面向过程和面向对象
# 1.2.1 面向过程
# 典型代表:C语言
# 适合开发中小型项目
# 1.2.2 面向对象
# 典型代表:Java、Python
# 适合开发大型项目
# 1.2.3 区别
# 面向过程(手洗):需要实现一个功能的时候,看重的是过程,分析出一个个步骤,并把一个个步骤用一个个函数实现,再依次去调用一个个函数即可
# 面向对象(机洗):需要实现一个功能的时候,看重的是谁去帮我做这件事情
# 1.3 作用
# 面向对象编程(OOP)就是主要针对大型软件设计而提出的,可以使软件设计更加灵活,并且更好的进行代码复用。
# 1.4 三大特性
# 封装、继承和多态
二、类和对象
python
# 2. 类和对象(重点)
# 2.1 含义
# 2.1.1 类
# 类就是对一系列具有相同属性和行为的事物的统称。
# 属性就是特征,用来描述是什么样子的。
# 行为就是所具备的功能,用来说明它能做什么。
# 2.1.2 对象
# 对象就是类的具体表现,是类创建出来的真实存在的事物,也是面向对象编程思想的核心。
# 注意:python中万物皆对象
# 2.1.3 两者关系
# 开发中,先有类,再有对象。
# 2.2 定义类
# 语法格式:
# class className:
# """描述信息""" # 类文档字符串(相当于帮助文档)
# 类体
# 注意: 类名要符合标识符规定,同时遵循大驼峰命名法,见名知意。
# 示例1:以洗衣机类为例声明一个类
class Washer:
"""洗衣机类"""
pass # 占位符,表示空语句,运行时会直接跳过(不会报错)。
# 在类定义完成以后,可以创建类的实例,即实例化该类对象。
# 2.3 创建对象(实例化对象)
# 语法格式:
# 对象名 = 类名()
# 示例2:创建洗衣机对象
class Washer:
"""洗衣机类"""
pass
# 第一次实例化
w1 = Washer()
print(w1) # 默认显示对象在内存中的地址
# 第二次实例化
w2 = Washer()
print(w2)
# 内存地址不同,创建的是不同的对象。
# 需求:以人类为例,创建三个人类对象
# 1. 定义类:人类
class Person:
"""人类"""
pass
# 第一次实例化
p1 = Person()
print(p1) # <__main__.Person object at 0x0000026249A278C8>
# 第二次实例化
p2 = Person()
print(p2) # <__main__.Person object at 0x0000026249B3B4C8>
# 第三次实例化
p3 = Person()
print(p3) # <__main__.Person object at 0x0000026249B3B3C8>
# 2.4 类中定义方法
# 2.4.1 实例方法(方法即是函数)
# 由对象来调用,至少一个self参数,执行实例方法的时候,自动将调用该方法的对象赋值给self。
# 示例3:在人类中定义学习方法
class Person:
"""人类"""
def study(self): # 实例方法:必须要有self参数,用于代表对象本身
print("人类爱学习")
print(self)
# 第一次实例化
p1 = Person()
print(p1)
p1.study()
# 第二次实例化
p2 = Person()
print(p2)
p2.study()
# 对象调用实例方法时,python会自动将对象本身的引用(即内存地址)作为参数,传递到实例方法的第一个参数self里面。
# 注意:python中约定类中代表对象本身的参数为self,但这并不是官方硬性规定,可以使用别的名称替代。
# 2.5 类中定义属性(属性即是变量)
# 2.5.1 类属性
# 定义在类中,并且在函数体外的属性,类属性可以在类的所有实例之间共享值,也就是说在所有实例化的对象中公用。
# 示例4:在人类中定义类属性:年龄
class Person:
"""人类"""
age = 18 # 类属性(所有对象共有)
def study(self):
print("人类爱学习")
print(self)
# 第一次实例化
p1 = Person()
print("p1.age:", p1.age) # p1.age: 18
# 第二次实例化
p2 = Person()
print("p2.age:", p2.age) # p2.age: 18
# 注意:类属性不仅可以通过对象名访问,也可以通过类名访问。
print("Person.age:", Person.age) # Person.age: 18
# 2.5.2 实例属性
# 定义在类的方法中的属性,只作用于当前对象中,即仅对象独有。
# 格式:self.属性名/对象名.属性名
# 示例5:
class Person:
"""人类"""
age = 18 # 类属性(所有对象共有)
def study(self):
print(f"{self.name}爱学习") # 实例方法内定义实例属性:对象名.属性名/self.属性名
# 第一次实例化
p1 = Person()
# 给实例属性赋值
p1.name = "冰冰"
p1.study()
# 第二次实例化
p2 = Person()
# 给实例属性赋值
p2.name = "麦芽"
p2.study()
# 注意:实例属性只能通过对象名访问,如果通过类名访问,也会报错。
# print(Person.name) # 报错
# 总结:类属性属于类,是公共的,大家都能使用,可以通过类名访问,也能通过对象名访问;实例属性属于对象,仅对象独有,只能由对象名访问,不能由类名访问。
class Person:
age = 18 # 类属性
# 实例化对象
p1 = Person()
# 可以直接通过类名访问类属性
print("Person.age:", Person.age) # Person.age: 18
# 也可以通过对象名访问类属性
print("p1.age:", p1.age) # p1.age: 18
# 第二次实例化
p2 = Person()
print("p2.age:", p2.age) # p2.age: 18
class Person:
def play(self):
print(f"{self.name}在玩游戏") # 实例属性
# 不能通过类名访问实例属性
# print("Person.name:", Person.name) # 报错
# 只可以通过对象名访问,并且实例属性只能当前对象使用
# 实例化对象
p1 = Person()
# p1.play() # 报错
p1.name = "bingbing"
p1.play() # bingbing在玩游戏
# 第二次实例化
p2 = Person()
# p2.play() # 报错
p2.name = "susu"
p2.play() # susu在玩游戏
3. 构造函数
python
# 3. 构造函数(__init__()) ---掌握
# 3.1 含义
# 是一个特殊的实例方法,类实例对象时,Python会自动执行它。
# 示例1:
class Person:
def __init__(self):
print("我是人类!")
p1 = Person() # 我是人类!
# 3.2 作用
# 通常用来属性初始化或赋值操作。
class Person:
def __init__(self):
self.name = "bingbing"
self.age = 18
self.sex = "女"
def say_hello(self):
print(f"你好呀,我叫{self.name},今年{self.age}岁了,性别为{self.sex}。")
# 实例化对象
p1 = Person()
p1.say_hello()
# 可以在__init__方法中定义一些参数,在实例化对象时,直接给这些参数赋值
class Person:
def __init__(self, name, age, sex):
print("我是人类!")
self.name = name
self.age = age
self.sex = sex
def say_hello(self):
print(f"你好呀,我叫{self.name},今年{self.age}岁了,性别为{self.sex}。")
# 实例化对象
p1 = Person("冰冰", 18, "女")
p1.say_hello() # 你好呀,我叫冰冰,今年18岁了,性别为女。
# 第二次实例化
p2 = Person("苏苏", 18, "女")
p2.say_hello() # 你好呀,我叫苏苏,今年18岁了,性别为女。
# 第三次实例化
p3 = Person("帅哥", 27, "男")
p3.say_hello() # 你好呀,我叫帅哥,今年27岁了,性别为男。
4. 析构函数
python
# 4. 析构函数(__del__()) ---熟悉
# 4.1 作用
# 1. 程序执行结束后,Python会自动执行__del__方法(即默认在程序最后执行)。
class Person:
def __init__(self):
print("我是实例化对象时会自动执行的__init__方法。")
def __del__(self):
print("我是程序执行结束后会自动执行的__del__方法。")
p = Person()
# 运行结果:
# 我是实例化对象时会自动执行的__init__方法。
# 我是程序执行结束后会自动执行的__del__方法。
print(123)
print(456, 789)
# 运行结果:
# 我是实例化对象时会自动执行的__init__方法。
# 123
# 456 789
# 我是程序执行结束后会自动执行的__del__方法。
# 2. 删除对象时,Python会自动执行它。
class Person:
def __del__(self):
print("对象被删除!")
p1 = Person()
del p1 # 对象被删除!
print("哈哈哈") # 哈哈哈
p2 = Person()
del p2 # 对象被删除!
# 4.2 使用场景
# 对象即将被销毁的时候需要做的一些工作,比如:关闭文件、关闭数据库、关闭各种资源...
# 5. __str__()
# 5.1 作用
# 对象的描述信息。如果类中定义了str方法,那么在打印对象时,默认输出该方法的返回值,也就是打印这个方法中return的数据。
# 注意: __ str__()必须返回一个字符串
class C:
pass
c = C()
print(c)
class C:
def __str__(self):
return "这里是str方法的返回值" # 必须有返回值,而且一定是字符串类型
# return 123 # 报错,类型错误
c = C()
print(c)
13.封装&单继承
课程内容
python
1. 封装
2. 单继承
3. 方法的重写
4. 新式类写法
一、封装
python
# 面向对象三大特征:
# 1. 封装:根据职责 将属性 和方法 封装到一个抽象的类中
# 2. 继承:实现代码的重用,相同的代码不需要重复的编写
# 3. 多态:不同的对象调用相同的方法,产生不同的执行结果,能够增加代码的灵活度
# 1. 封装(熟悉)
# 1.1 含义
# 将复杂的信息、流程给包起来,内部处理,让使用者只需要通过简单的操作步骤,就能实现。
# 面向对象编程的第一步: 1.将属性和方法封装 到一个抽象的类中
# 2.外界使用类创建对象,然后让对象调用方法
# 3.对象方法的细节都被封装在类的内部)
# 1.2 类本质上就是一种封装
class Washier:
def __init__(self): # 构造函数
self.width = 450 # 实例属性
self.height = 800
def dewatering(self): # 实例方法: 脱水
print("执行脱水操作")
def poaching(self): # 实例方法: 漂洗
print("执行漂洗操作")
# 实例化对象
wa = Washier()
# 通过对象调用实例方法
wa.dewatering()
# 需求:定义一个人类,类中有实例属性:姓名,年龄,实例方法:打招呼
class Person:
def __init__(self, name, age):
self.name = name # 实例属性
self.age = age
def say_hello(self):
print("你好呀!")
# 实例化对象
p1 = Person("冰冰", 18)
# 通过对象调用实例方法
p1.say_hello() # 你好呀!
# 通过对象访问实例属性
print(p1.name) # 冰冰
print(p1.age) # 18
# 1.3 类中定义私有
# 私有:即类独有的,一般情况下不会去外面使用。
# 1.3.1 私有权限
# 注意:在Python中没有专门的修饰符用于定义属性/方法的私有,如果该属性/方法不希望在类对象外部被访问,前边使用两个下划线__。
class Person:
def __init__(self, name, age):
self.name = name # 实例属性
self.__age = age # 不希望在类的外部被使用,所以加了两个__,只允许在类的内部使用
def say_hello(self):
print("你好呀!")
def tell_age(self): # 实例方法
print("姓名:", self.name)
print("年龄:", self.__age)
pe = Person("冰冰", 18)
# 在类的外部使用name与age
print(pe.name)
# print(pe.age) # 报错,Person对象里面没有age这个属性
# print(pe.__age) # 报错
# 第一种:了解
print(dir(pe)) # dir()查看对象的所有的属性和方法
print(pe._Person__age) # 能访问到
pe._Person__age = '25' # 能修改,没有特殊需求不要这么做
# Python 中,并没有真正意义的私有,在给属性、方法命名时,实际是对名称做了一些特殊处理,使得外界无法访问到。
# 第二种方式:在类中定义方法使用
pe.tell_age()
# 总结:Python中并没有真正的私有化,但是有一些和命名有关的约定,来让开发人员处理一些需要私有化的情况。
# 1.4 封装的意义
# 1. 将属性和方法放到一起做为一个整体,然后通过实例化对象来处理;
# 2. 隐藏内部实现细节,只需要和对象及其属性和方法交互就可以了;
# 3. 对类的属性和方法增加 访问权限控制。
二、单继承
python
# 2.单继承(掌握)
# 2.1 继承
# 2.1.1 含义
# Python中继承指的是多个类之间的所属关系,即让类和类之间转变为父子关系,子类默认继承父类的所有属性和方法。
# 2.1.2 作用
# 实现代码的重用,相同的代码不需要重复的编写,提高开发效率。
# 2.1.2 语法
# class 类名(父类名):
# """类的描述信息"""
# 类体
# 注意:父类可以写多个,类名之间用","分隔,如果不写,默认继承object(顶级父类)。
# 2.1.3 分类
# 1.单继承(只有一个父类)
# 2.多继承(有多个父类)
# 2.2 单继承(只有一个父类)
class Person:
"""人类:父类"""
age = 18 # 类属性
def eat(self): # 实例方法
print("我会干饭")
def sleep(self):
print("干完饭了就睡觉")
class Man(Person):
"""男人类:子类"""
pass # 占位符,代码里面类下面不写东西,会自动跳过,不会出错
man = Man()
# 访问类属性:既能通过类名访问,也能通过对象名访问
print(Man.age) # 18
print(man.age) # 18
# 调用实例方法
man.eat() # 我会干饭
man.sleep() # 干完饭了就睡觉
class Woman(Person):
"""女人类:子类"""
pass
woman = Woman()
# 访问类属性
print(woman.age) # 18
print(Woman.age) # 18
# 调用实例属性
woman.eat() # 我会干饭
woman.sleep() # 干完饭了就睡觉
# 总结: 继承可以使子类拥有父类的属性和方法
# 2.3 继承的传递(多重继承)
# 举例:A/B/C类 C类(子类)继承于B类(父类),B类(子类)继承于A类(父类),C类具有A/B类的属性和方法
# 2.3.1 含义
# 子类拥有父类的父类的属性和方法。
# 示例1:
class A1:
"""A1类:A2的父类"""
thing = "传家宝"
def skill(self):
print("祖传好手艺")
class A2(A1):
"""A2类:A1的子类,A3的父类"""
pass
# 实例化A2对象
a2 = A2()
print(a2.thing) # 传家宝
a2.skill() # 祖传好手艺
class A3(A2):
"""A3类:A2的子类"""
pass
# 实例化A3类对象
a3 = A3()
print(a3.thing) # 传家宝
a3.skill() # 祖传好手艺
# 总结:继承的传递性就是子类拥有父类以及父类的父类中的属性和方法。
三、方法的重写
python
# 3.方法的重写(掌握)
# 3.1 含义
# 重写指在子类中定义与父类相同名称的方法。
# 3.2 分类
# ① 覆盖父类方法
# ② 对父类方法进行扩展
# 3.3 覆盖父类方法
# 在子类中定义一个跟父类同名的方法,会调用子类重写的方法
# 示例1:
class Parent:
"""Parent类:父类"""
def connect(self):
print("打电话联系。")
class Child(Parent):
"""Child类:子类"""
pass
child = Child()
child.connect() # 打电话联系。(子类中没有定义connect方法,使用父类中的connect方法。)
class Parent:
"""Parent类:父类"""
def connect(self):
print("打电话联系。")
class Child(Parent):
"""Child类:子类"""
def connect(self):
print("社会发展了,可以直接视频联系了。")
child = Child()
child.connect() # 社会发展了,可以直接视频联系了。(子类中定义connect方法,直接使用自己的connect方法。)
# 3.4 对父类方法进行扩展
# 3.4.1 含义
# 继承父类的方法,子类可以增加自己的功能
# 3.4.2 实现方式
# ① 父类名.方法名(self)
# ② super().方法名() ---推荐使用
# ③ super(子类名,self).方法名()
class Parent:
"""Parent类:父类"""
def connect(self):
print("打电话联系。")
class Child(Parent):
"""Child类:子类"""
def connect(self):
# 1.父类名.方法名(self)
# Parent.connect(self)
# 2.super().方法名() ---推荐使用
super().connect()
# 3.super(子类名, self).方法名() ---过时
# super(Child, self).connect()
print("社会发展了,可以直接视频联系了。")
child = Child()
child.connect() # 打电话联系。\n社会发展了,可以直接视频联系了。(既拥有了父类的功能,又扩展了新功能)
# 需求:
# 1. 创建Person类,属性有姓名name、年龄age、性别sex,方法有printInfo方法,用于打印这个人的信息。
# 2. 创建Student类,继承Person类,属性有学院college,班级class,重写父类printInfo方法,调用父类方法打印个人信息外,将学生的学院、班级信息也打印出来。
# 代码实现
class Person:
"""Person类"""
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
def printInfo(self):
print(f"我的姓名:{self.name},我的年龄:{self.age},我的性别:{self.sex}。")
# 代码测试
# p = Person("冰冰", 18, "女")
# p.printInfo()
class Student(Person):
"""Student类:继承Person类"""
def __init__(self, name, age, sex, college, class_name):
# self.name = name
# self.age = age
# self.sex = sex
# 优化代码
# super().__init__() # 报错,缺少参数
super().__init__(name, age, sex)
self.college = college
self.class_name = class_name
def printInfo(self):
# 方式一:覆盖父类方法
# print(f"我的姓名:{self.name},我的年龄:{self.age},我的性别:{self.sex},我的学院:{self.college},我的班级:{self.class_name}。")
# 方式二:对父类方法进行扩展
# 继承父类功能
super().printInfo()
# 扩展功能
print(f"我的学院:{self.college},我的班级:{self.class_name}。")
s1 = Student("冰冰", 18, "女", "六星", "2202-10班")
s1.printInfo()
四、 新式类写法
python
# 4. 新式类写法(了解)
# 新式类:继承了object的类以及该类的子类都是新式类。
# 原始写法:
class A:
"""类的描述信息"""
类体
# 第二种写法:
class A():
"""类的描述信息"""
类体
# 第三种写法: ---推荐使用
class A(object):
"""类的描述信息"""
类体
# 总结:Python3版本中object是顶级父类,如果一个类没有继承任何类,则默认继承object类,因此Python3中的类都是新式类。
14.多继承、多态
课程内容
python
1. 多继承
2. 多态
3. 静态方法
4. 类方法
1. 多继承
python
# 1. 多继承(熟悉)
# 1.1 含义
# 多继承就是子类可以拥有多个父类,并且具有所有父类的属性和方法。
class Father(object):
"""父类一"""
def money(self):
print("拥有一百万财产需要被继承")
class Mother(object):
"""父类二"""
def appearance(self):
print("绝世容颜需要被继承")
class Son(Father, Mother):
"""子类"""
pass
son = Son()
son.money()
son.appearance()
# 总结:多继承可以让子类同时具有多个父类的属性和方法
# 思考如果不同的父类中存在同名的方法,子类对象在调用方法时,会调用哪一个父类中的方法呢?
# 1.2 不同的父类存在同名的方法
# 注意:(开发时,应尽量避免这种容易产生混淆的情况。)如果父类之间存在同名的属性或方法时,应该尽量避免使用多继承。
class Father(object):
"""父类一"""
def weight(self):
print("爸爸体重一百八")
class Mother(object):
"""父类二"""
def weight(self):
print("妈妈体重九十八")
# class Son(Father, Mother):
class Son(Mother, Father):
"""子类"""
pass
son = Son()
son.weight()
# 如果有多个父类之间存在同名方法时,采用就近原则,先继承谁就使用谁的方法。
class Father(object):
"""父类一"""
def weight(self):
print("爸爸体重一百八")
class Mother(object):
"""父类二"""
def weight(self):
print("妈妈体重九十八")
# class Son(Father, Mother):
class Son(Mother, Father):
"""子类"""
def weight(self):
print("自己体重一百二")
son = Son()
son.weight() # 自己体重一百二
# 1.3 方法搜索顺序(了解)
# 1.3.1 作用
# Python中内置属性__mro__可以查看方法搜索顺序,用于确定子类调用方法的顺序。
# 1.3.2 语法
# 类名.__mro__
class Father(object):
"""父类一"""
def weight(self):
print("爸爸体重一百八")
class Mother(object):
"""父类二"""
def weight(self):
print("妈妈体重九十八")
# class Son(Father, Mother):
class Son(Mother, Father):
"""子类"""
def weight(self):
print("自己体重一百二")
son = Son()
son.weight()
print(Son.__mro__)
# 1.3.3 总结
# 1. 多继承有同名方法时,搜索方法时,会先按照__mro__的输出结果,按照从左往右的顺序查找。
# 2. 如果在当前类(子类)的方法中找到了,就直接执行,不再搜索
# 3. 如果找到最后一个类(object类),还没有找到方法,程序就会报错
# 1.4 多继承弊端
# 容易引发冲突,会导致代码设计的复杂度增加。
2. 多态
python
# 2. 多态(掌握)
# 2.1 含义
# 指同一行为,具有多个不同的表现形式。
# 2.2 两大前提
# 1. 继承
# 2. 重写
class Animal(object):
"""父类:动物类"""
def shout(self):
print("动物会叫")
class Cat(Animal):
"""子类一:猫类"""
def shout(self): # 重写父类同名方法
print("小猫喵喵喵")
class Dog(Animal):
"""子类二:狗类"""
def shout(self): # 重写父类同名方法
print("小狗汪汪汪")
class Pig(Animal):
"""子类三:猪类"""
def shout(self):
print("小猪哼哼哼")
cat = Cat()
cat.shout()
dog = Dog()
dog.shout()
pig = Pig()
pig.shout()
# 2.3 同一种调用方式,能够根据传入对象的不同,产生不同的执行结果
class Animal(object):
"""父类:动物类"""
def shout(self):
print("动物会叫")
class Cat(Animal):
"""子类一:猫类"""
def shout(self): # 重写父类同名方法
print("小猫喵喵喵")
class Dog(Animal):
"""子类二:狗类"""
def shout(self): # 重写父类同名方法
print("小狗汪汪汪")
class Pig(Animal):
"""子类三:猪类"""
def shout(self):
print("小猪哼哼哼")
# 定义一个统一的接口
def test(obj): # obj:普通形参
obj.shout()
# 实例化子类对象
cat = Cat()
dog = Dog()
pig = Pig()
# 调用接口,多种执行结果
test(cat) # 传入的是cat对象,调用cat对象的shout方法
test(dog)
test(pig)
# 需求:利用多态的思想,编写程序模拟"主人"(Master)喂养"宠物"(Pet)的场景。
class Pet(object):
"""宠物类:父类"""
def eat(self):
print("宠物吃东西")
class Dog(Pet):
"""子类一:狗类"""
def eat(self):
print("狗吃狗粮")
class Cat(Pet):
"""子类二:猫类"""
def eat(self):
print("猫吃鱼")
class Pig(Pet):
"""子类三:猪类"""
def eat(self):
print("猪吃猪饲料")
class Master(object):
"""主人类"""
def feed(self,pet):
pet.eat()
ma = Master()
dog = Dog()
ma.feed(dog)
cat = Cat()
ma.feed(cat)
pig = Pig()
ma.feed(pig)
3. 静态方法
python
# 3.静态方法(熟练运用)
# 3.1 含义
# 使用装饰器@staticmethod来进行修饰,静态方法既不需要传递类对象也不需要传递实例对象(形参没有self/cls参数限制)
# 注意: 静态方法与类无关,可以将其转换成普通函数使用
# 3.2 定义格式
# class 类名:
# @staticmethod
# def 方法名(形参):
# 方法体
class Person(object):
@staticmethod # 静态方法:类中的函数,不需要实例
def study():
print("人类会学习")
# 注意: 静态方法既可以使用对象访问又可以使用类访问
Person.study()
pe = Person()
pe.study()
class Person(object):
@staticmethod # 静态方法:类中的函数,不需要实例
def study(name):
print(f"{name}会学习")
Person.study('小明')
pe = Person()
pe.study('小明')
# 3.3 作用
# 取消不需要的参数传递,有利于减少不必要的内存占用和性能消耗。
# 3.4 应用场景
# 当方法中既不需要使用实例对象,也不需要使用类对象时,定义静态方法。
4. 类方法
python
# 4. 类方法(熟练运用)
# 4.1 含义
# 使用装饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数。
# 4.2 定义格式
# class 类名:
# @classmethod
# def 方法名(形参):
# 方法体
class Person(object):
@classmethod
def sleep(cls): # cls代表类对象
print(cls)
print("人类在睡觉")
print(Person)
# 通常是使用类名调用类方法
Person.sleep()
# 注意:类方法内部可以访问类属性,或者调用其他的类方法
class Person(object):
name = '小明' # 类属性
@classmethod
def sleep(cls): # cls代表类对象
print(cls)
print("人类在睡觉")
print(cls.name)
print(Person)
Person.sleep()
# 4.3 应用场景
# 类方法一般和类属性配合使用,当方法中需要使用类时也可以定义类方法。
5. 总结
python
# 5. 三种方法内部访问属性对比总结
# 1. 实例方法: 方法内部访问实例属性,方法内部可以通过类名.类属性名来访问类属性
# 2. 静态方法: 方法内部不需要访问实例属性和类属性,如果要访问类属性只能通过类名.类属性名访问,不能访问实例属性
# 3. 类方法: 方法内部只需要访问类属性,可以通过cls.类属性名访问类属性,不能访问实例属性
# 示例1:实例方法访问类属性
class Person(object):
name = "小明" # 类属性
def __init__(self):
self.age = 18 # 实例属性
def play(self): # 实例方法
# 在实例方法中访问类属性
# print(f'{name}在玩游戏') # 报错,name属性没有被定义
print(f'{self.name}在玩游戏')
print(f'{Person.name}在玩游戏')
print(self.age)
pe = Person()
pe.play()
# 示例2: 静态方法中访问类属性
class Person(object):
name = '小明' # 类属性
def __init__(self):
self.age = 18 # 实例属性
@staticmethod # 静态方法:类中的函数,不需要实例
def play():
# print(f'{name}在玩游戏') # 报错,name属性没有被定义
print(f'{Person.name}在玩游戏') # 没意义,静态方法的意义本身就是与类无关,既不需要传递类对象也不需要传递实例对象
# print(self.age) # 报错,不能访问,没有self这个参数
Person.play()
pe = Person()
pe.play()
# 示例3:类方法中访问类属性、实例属性
class Person(object):
name = '小明' # 类属性
def __init__(self):
self.age = 18 # 实例属性
@classmethod
def play(cls): # cls代表类对象
print(cls)
# print(f'{name}在玩游戏') # 报错,name属性没有被定义
print(f'{cls.name}在玩游戏') # 在类方法中方为类属性
print(f'{Person.name}在玩游戏') # 没有必要,cls直接代表了类对象
# print(self.age) # 报错,在类方法中访问实例属性不能访问
# print(cls.age) # 报错,类对象没有这个属性
print('类对象:', Person)
Person.play()
pe = Person()
print('这是实例化的对象:', pe)
15.文件读写
1.内容
本次课程为Python基础的第十五次课程,主要内容有以下:
1. 基础操作
2. 读写操作
3. 编码格式
4. 目录常用操作
人群基础:第一次接触Python的小白、细节需要根据人群确定。
2.教学目的
让学员熟练掌握文件操作以及目录常用操作
3.教学重点
重点:基础操作、目录常用操作、读写操作
难点: 访问模式
4.教学过程
1.文件基础操作
1.1 知识说明
让学员掌握文件基础操作。
程度: 熟练掌握
1.2 知识讲解
1.2.1 文件
文件就是存储在某种长期储存设备上的一段数据。
长期存储设备包括:硬盘、U盘、移动硬盘、光盘...
1.2.2 作用
读取内容、写入内容、备份内容...
总结: 文件作用就是把一些内容(数据)存储存放起来,可以让程序下一次执行的时候直接使用,而不必重新制作一份,省时省力。
1.2.3 文件的存储方式 --不讲
计算机的CPU如果想要访问保存在磁盘上的文件,第一步应该先把磁盘中的文件数据加载到内存中,因为内存的读写速度要比磁盘的读写速度快很多,那么计算机能够识别什么数据呢?
在计算机中,只能识别二进制方式保存的数据,因此保存在磁盘中的每一个文件本质上都是以二进制方式保存。但是,在我们日常使用中,通常会把文件分成两种类型。
- 文本文件
- 可以使用文本编辑软件查看
- 本质上还是二进制文件
- 如:py、txt等...
- 二进制文件
- 例如:图片、音频、视频等
- 二进制文件不能使用文本编辑软件查看
- 保存的内容不是给人直接阅读的,而是提供给其他软件使用的。
无论是哪种文件,本质上都是以二进制方式存储的。
1.2.4 文件的基本操作
在计算机中要操作文件步骤非常固定,一共包含三个:
- 打开文件
- 读、写文件
- 读 将文件内容加载到内存
- 写 将内存内容写入到磁盘文件中
- 关闭文件
注意:可以只打开和关闭文件,不进行任何读写操作。
1.2.5 文件对象的方法
-
open(): 创建一个file对象,默认以只读模式打开
read(n): n表示从文件中读取的数据的长度,没有传n值则默认一次性读取文件的所有内容
-
write(): 将指定内容写入文件
-
close(): 关闭文件
1.2.6 属性
- 文件名.name: 返回要打开的文件的文件名,可以包含文件所在的具体路径
- 文件名.mode: 返回文件的访问模式
- 文件名.closed: 检测文件是否关闭,关闭则返回True,没关闭返回Falsel
示例1:
new -> File -> test.txt
test.txt:
bingbing18
py01.txt:
python
#1.打开文件
f = open('test.txt')
print(f) #f是文件对象
print(f.name) #文件名
print(f.mode) #访问模式
print(f.closed) #是否关闭文件
#2.关闭文件
f.close()
print(f.closed)
2.读写操作
2.1 知识说明
让学员掌握文件读写操作。
程度: 熟练掌握
2.2 知识讲解
2.2.1 read(n)
作用: n表示从文件中读取的数据的长度,没有传n值或是负值则默认一次性读取文件的所有内容
示例:
python
#1.打开文件
f = open('test.txt')
#print(f) #f是文件对象
#print(f.name) #文件名
#print(f.mode) #访问模式
#print(f.closed) #是否关闭文件
#2.读取文件内容
#f.read() #没有打印,所以没有显示结果
#print(f.read()) #没有设置n值,默认一次性全部读取
print(f.read(5)) #最多读取5个数据
#3.关闭文件
f.close()
print(f.closed)
引导: 前面讲name属性的时候有说到可以包含文件所在的具体路径,怎么样做呢?
示例2:
桌面新建test.txt
test.txt:
hahahaha
python
#f2 = open("test.txt")
#print(f2.read())
#f2.close()
f2 = open(r"C:\Users\1\Desktop\test.txt") #r取消转义
print(f2.name)
#绝对路径:就是完整的地址,比如湖南省长沙市岳麓区芯城科技园2期7栋1楼
#print(f2.read())
print(f2.read(3))
f2.close()
2.2.2 readline()
read()方法在默认情况下会把文件的所有内容一次性全部读取到内存中,如果文件非常大,使用read()一次性把所有内容加载到内存,会给内存带来非常大的压力,对内存的占用会非常严重。因此我们可以使用readline()。
作用: 一次读取一行内容,方法执行完,会把文件指针移动到下一行,准备再次读取。
示例:
test.txt:
bingbing18
hahaha
yyds
py01:
python
f = open("test.txt")
# print(f.readline())
# print(f.readline())
# print(f.readline())
while True:
#读取一行内容
text = f.readline()
#如果不能读到内容,就需要退出循环
if not text: #没有读取到就退出循环
break
print(text)
f.close()
2.2.3 readlines()
作用: 按照行的方式把文件内容一次性读取,返回的是一个列表,每一行的数据就是一个元素
示例:
test.txt:
bingbing18
hahaha
yyds
py01:
python
f = open("test.txt")
text = f.readlines()
print(text)
print(type(text))
for i in text:
print(i)
f.close()
2.2.4 访问模式
错误示例:
python
f = open('test.txt')
print(f.read()) #能读到文件内容
#进行写操作
#f.write("heiheihei") #报错,不支持写操作
f.close()
思考: 为什么会报错,不支持写的操作呢?
因为前面讲过open()默认以只读模式打开,只能读,不能写,要写需要更改访问模式。
1. r: 只读模式(默认模式),文件必须存在,不存在就会报错。
示例1:
python
f = open('test01.txt')
#print(f.read()) #报错,没有这个文件,找不到。
f.close()
2.w: 只写模式,文件存在则会先清空文件内容,再写入添加内容,不存在则创建新文件。
示例1.2:
python
f = open('test.txt','w')
#print(f.read()) #报错,只写模式不支持读操作
f.write("emmmm...") #重新编辑文件内容,原先内容清空了。
#print(f.read()) #报错
f.close()
思考: 如何让读写操作都被支持呢?
3. +: 表示可以同时读写某个文件
注意:使用+会影响文件的读写效率,开发中更多时候会以只读 、只写的方式来操作文件。
3.1 r+: 可读写文件,文件不存在就会报错
3.2 w+: 先写再读,文件存在就重新编辑文件,不存在则创建新文件
示例1.3:
python
f = open('test.txt','w+')
#print(f.read())
f.write("hello python") #重新编辑文件内容,原先内容清空了。
print(f.read()) #没有读取出来,涉及光标,写完之后光标在文件内容后面,读取是从光标以后开始读,所以读取出来是空白
f.close()
发现全都是重新编辑,原来的内容都被清空了,那要在原来的基础上添加新的内容要怎么做呢?
4. a: 追加模式,不存在则创建新文件进行写入,存在则在文件原有内容的基础上添加新的内容,也就是说,新的内容将会被写入到已有内容之后。
示例1.4:
python
f = open('test.txt','a') #a就是append的缩写,追加的意思
#print(f.read())
f.write("test is being written...")
#print(f.read()) #不支持读操作
f.close()
注意改变光标的位置
光标,涉及指针,指针广泛用于C语言和C++,其实python并没有指针这个概念,但是有指针的体现。
扩展:文件指针
文件指针标记从哪个位置开始读取数据。
示例2:
python
f = open('test.txt','w+')
f.write("Hello BingBing")
print(f.read()) #读取出来是空白
f.close()
#第一种方式:再改为只读模式读取
f = open('test.txt')
#f.write("Hello BingBing")
print(f.read())
f.close()
第二种方式:
2.2.5 文件定位操作
tell()和seek()
tell(): 显示文件内的当前位置,即文件指针当前位置
seek(offset,whence): 移动文件读取指针到指定位置
offset: ---偏移量,表示要移动的字节数
whence: ---起始位置,表示移动字节的参考位置,默认值是0,0代表将文件开头作为参考位置;1代表将当前位置作为参考位置,2代表将文件结尾作为参考位置
注意: 现在只要记住seek(0,0)会将光标移到文件开头
示例:
python
f = open('test.txt','w+')
f.write('hello,BingBing')
pos = f.tell()
print('当前光标的位置:',pos) # 14--文件内容长度
#把光标移到文件开头
f.seek(0,0)
#print("现在光标的位置:",pos) #两次光标的位置都是一样的
#因为两次都是使用的pos
pos2 = f.tell()
print("第二次光标的位置:",pos2)
print(f.read())
f.close()
3.编码格式
3.1 知识说明
让学员熟悉编码格式
程度: 熟悉
3.2 知识讲解
3.2.1 with open
如果每次都按照open...close...这种方式去写的话,实在太繁琐,python引入了with语句来自动帮我们调用close()方法
作用: 代码执行完,系统会自动调用f.close(),可以省略文件关闭步骤
示例1.1:
python
with open('test.txt','w') as f: #注意缩进!!!
f.write('emmm...')
print(f.closed) #True ---代表文件已关闭
2.2.2 编码格式
Python3中的open()多了比python2要多了几个参数,其中包括一个encoding参数,这个encoding就是用来指定被操作文件的字符编码的。
从之前我们进行读写操作是可以发现encoding参数显然是可以不指定的,这时候就会用一个"默认字符编码",需要注意的是encoding参数的默认值是与平台有关的,比如window上默认字符编码为GBK,Linux默认字符编码为UTF-8
示例1.2:
python
with open('test.txt','w') as f: #注意缩进!!!
f.write('输的什么液,想你的夜')
print(f.closed) #True ---代表文件已关闭
#乱码,因为写入中文字符时,文件编码格式为gbk,此时pycharm中的文件会将你输入的中文显示为16进制数,并会提示你用gbk编码reload文件。
#这时候就要将GBK改成utf-8格式
with open('test.txt','w',encoding = "utf-8") as f:
f.write("输的什么液,想你的夜")
print(f.closed)
示例2:
test01.txt:
宝
我昨天去输液了
输的什么液
想你的夜
python
#with open('test01.txt') as f:
#报错,在文本文件中夹杂了一些非法编码的字符。
with open('test01.txt',encoding="utf-8") as f:
print(f.read())
案例:图片复制
注意:前面讲的默认都是文本文件,并且是UTF-8编码的文本文件。要读取二进制文件,比如图片、视频等等,用'rb'模式打开文件即可。
示例:
python
"""
1.新建一个文件夹
2.读取图片,为什么要先读取图片?因为图片是一个二进制文件,想要写入二进制文件的话必须要先拿到
3.写入图片
"""
import os
desk = "C:\\Users\\1\\Desktop\\新建文件夹\\"
#打开原文件并读取
with open(desk+"鱼.png", "rb") as f:
img = f.read()
# print(img)
# 读取的内容写入到新文件夹中
with open("D:\\python\\py_study\\鱼.png","wb") as f:
f.write(img)
4.目录常用操作
4.1 知识说明
让学员熟练掌握目录常用操作
程度: 熟练掌握
4.2 知识讲解
有时候,需要对文件进行重命名、删除等操作,python中的os模块中就有这些功能,需要导入os模块。
4.2.1 常用操作
- 文件重命名:os.rename(目标文件名,新文件名)
- 删除文件: os.remove(目标文件名)
- 创建文件夹: os.mkdir(文件夹名)
- 获取当前目录: os.getcwd()
- 获取目录列表: os.listdir(目录)
- 删除文件夹: os.rmdir(文件夹名)
示例:
python
import os #导入os模块
#1.文件重命名: os.rename(旧名,新名)
#os.rename('test01.txt','test02.txt')
#2.删除文件: os.remove
#os.remove('test02.txt')
#os.remove('D:\Python\pyth02\py\test02.txt')
#3.创建文件夹: os.mkdir
#os.mkdir('zs')
#4.删除文件夹: os.rmdir
#os.rmdir('zs')
#5.获取当前目录: os.getcwd
#print(os.getcwd())
#6.获取目录列表 os.listdir
print(os.listdir()) #获取当前目录的列表
print(os.listdir('../'))#获取上一级目录的列表
4.2.2 综合案例
需求:批量操作当前目录下的文件
-
批量添加前缀
-
批量删除前缀
代码实现:
python
#导入os模块
import os
#显示功能列表
print("功能列表\n1.批量添加\n2.批量删除")
#输入前缀
prefix = input("请输入前缀:")
#用户输入功能序号
num = int(input("请输入功能序号:"))
#获取当前目录下的所有目录和文件--获取目录列表
file_list = os.listdir()
#print(file_list)
#遍历判断是否是文件
for file in file_list:
#os.path.isfile(file) #判断是否是文件,后面内置模块也会讲解。
if not os.path.isfile(file):
continue #如果不是文件,跳过此次循环,执行下一次循环
if num == 1: #添加前缀,本质上就是重命名
os.rename(file,prefix+file)
print(f"{file}添加前缀执行完成")
elif num == 2: #删除前缀,本质上也是重命名操作
#判断是否以prefix开头
if file.startswith(prefix):
os.rename(file,file[len(prefix):]) # 通过切片截取后面文件名
print(f"{file}删除前缀执行完成")
else:
print("请输入正确序号!")
break
#else: #else在循环正常完成时执行,意味着循环没有遇到任何break语句(即for不是通过break跳出而中断的)。
# print("执行成功")
5.教学后记
- 能够熟练掌握文件基础操作
- 能够熟练使用不同的访问模式
- 能够熟练掌握目录常用操作
- 能够熟悉编码格式
- 能够熟练掌握文件读写操作
6.作业布置
16. 正则基础
课程内容
python
1. 正则表达式
2. findall()
3. 贪婪和非贪婪
1. 正则表达式
python
1. 正则表达式
1.1 概念
记录文本规则的代码。
1.2 特点
1. 语法偏复杂,可读性较差
2. 通用性很强,适用于多种编程语言。
1.3 简单使用
# 1. 导入模块
import re
# 2. 使用match()进行匹配操作
# re.match(pattern, string, flags=0):从字符串的开始位置进行匹配,匹配成功返回match对象,匹配失败,返回None
# pattern: 匹配的正则表达式
# string:要匹配的字符串
# flags:标志位,用于控制正则表达式的匹配方式,如是否区分大小写,是否多行匹配等,多数情况下使用不到。
res = re.match("最", "最后一次课")
print(res) # <re.Match object; span=(0, 1), match='最'>
# 3.匹配到数据,使用group()方法提取数据
print(res.group()) # 最
示例:
res = re.match("嗯", "哈哈")
# print(res) # None
# print(res.group()) # 报错
1.4 匹配单个字符
import re
# 1. .:匹配任意1个字符(除\n以外)
res = re.match(".", "1aA\t\n嗯!")
print(res.group())
# 2. []:匹配[]中列举的字符
res = re.match('[pP]', "pPython") # 从开始位置匹配p或者P
print(res.group()) # p
# 需求:匹配pP
res = re.match('[p][P]', "pPython")
print(res.group()) # pP
# 注意:匹配连续数字或字母时,可以简写
res = re.match("[0123456789]", "0123456789")
# 简化写法:
res = re.match("[0-9]", "0123456789")
print(res.group())
# 需求:匹配5之外的任意数字
res = re.match("[012346789]", "0123456789")
# res = re.match("[012346789]", "56789") # 报错
# 简化写法:
# res = re.match("[0-46-9]", "0123456789")
print(res.group())
# 匹配所有小写字母:[a-z],匹配所有大写字母:[A-Z],匹配所有字母[a-zA-Z]
# 3. \d:匹配数字0-9
res = re.match("\d", "0123456789a")
print(res.group())
# 4. \D:匹配非数字
res = re.match("\D", "aA1一\n\t!")
print(res.group())
# 5. \s:匹配空白
res = re.match("\s", " \t 1h")
print(res.group())
# 6. \S:匹配非空白
res = re.match("\S", "1h! \t ")
print(res.group())
# 7. \w:匹配单词字符,即a-z、A-Z、0-9、_、汉字
res = re.match("\w", "aA1_一!\t ~")
print(res.group())
# 8.\W:匹配非单词字符
res = re.match("\W", "!\t ~aA1_一")
print(res.group())
1.5 匹配多个字符
# 1. *:匹配前一个字符出现0次或者无限次,即可有可无
res = re.match("\w*", "1a_一\t!?")
print(res.group()) # 1a_一
res = re.match("\w*", '\t!?')
print(res.group())
# 2. +:匹配前一个字符出现1次或无限次,即至少有1次
res = re.match("\d+", "1234abcd")
print(res.group())
res = re.match("\d+", "abcd")
# print(res.group()) # 报错
# 3. ?:匹配前一个字符出现1次或者0次,即要么有1次,要么没有
res = re.match("\d?", '123abc')
print(res.group())
res = re.match("\d?", "abc")
print(res.group())
# 4. {m}:匹配前一个字符m次
res = re.match("\d{3}", "123abc") # 匹配三个数字
# res = re.match("\d{3}", "12abc") # 报错
# res = re.match("\d{3}", "1234abc") # 123
print(res.group())
# 5. {m, n}:匹配前一个字符出现从m到n次,即最少匹配m次,最多匹配n次
# 注意:必须满足m<n的条件
# res = re.match("\d{3,1}", "123abc") # 报错
# res = re.match("\d{1,3}", "123abc") # 123
# res = re.match("\d{1,3}", "abc") # 报错,最少要匹配1次
# res = re.match("\d{1,3}", "1abc") # 1
# res = re.match("\d{1,3}", "12abc") # 12
res = re.match("\d{1,3}", "1234abc") # 123,最多只匹配3次
print(res.group())
1.6 匹配开头和结尾
# 1. ^:匹配字符串开头;表示对...取反
res = re.match('^py', "python")
print(res.group()) # py
# 注意:^在[]中才表示对...取反
res = re.match("[^py]", "1!\tpython") # [^py]表示匹配除p、y以外的字符
print(res.group())
# 2. $:匹配字符串结尾
res = re.match("bing$", "bing")
print(res.group())
# res = re.match("bin$", "bing") # 报错,字符"bing"不以"bin"结尾
print(res.group())
1.7 匹配分组
# 1. |:匹配左右任意一个表达式
res = re.match("abc|def", "abcdefg")
print(res.group())
res = re.match("\s|\d", " 1abc!")
print(res.group())
# 2. (ab):将括号中字符作为一个分组
# 需求:匹配邮箱
# res = re.match("\w*@qq\.com", "123@qq.com")
# res = re.match("\w*@qq\.com|\w*@126\.com|\w*@163\.com", "123@qq.com")
# 简化写法:
res = re.match("\w*@(qq|126|163)\.com", "123@qq.com")
print(res.group())
# 3. \num:引用分组num匹配到的字符串,经常在标签中被使用
res = re.match('<\w*>\w*</\w*>', '<html>login</html>')
print(res.group()) # <html>login</html>
# res = re.match('<(\w*)>\w*</\1>', '<html>login</html>')
# print(res.group()) # 报错,反斜杠的问题,加r原生字符串取消转义
res = re.match(r'<(\w*)>\w*</\1>', '<html>login</html>')
print(res.group()) # <html>login</html>
# res = re.match('<(\w*)>\w*</\\1>','<html>login</html>')
# print(res.group()) # <html>login</html>
# 注意: 前面的<>里面是什么,后面的<>就是是什么
# res = re.match('<(\w*)>\w*</\\1>', '<html>login</htmler>')
# print(res.group()) # 报错
# res = re.match('<\w*><\w*>.*</\w*></\w*>', '<html><body>登录页面</body></html>')
# print(res.group())
# res = re.match(r'<(\w*)><(\w*)>.*</\2></\1>', '<html><body>登录页面</body></html>') # 注意顺序,从外到内排序,编号从一开始,外面是1组,里面是2组
# print(res.group())
# 4. (?P<name>):分组起别名 --扩展
# 5. (?p=name):引用别名为name分组匹配到的字符串 --扩展
res = re.match(r'<(?P<l1>\w*)><(?P<l2>\w*)>.*</(?P=l2)></(?P=l1)>', '<html><body>登录页面</body></html>')
print(res.group()) # <html><body>登录页面</body></html>
# 需求:匹配网址
# 要求:前缀:www,后缀:.com/.cn/.net/.org
li = ['www.baidu.com', 'www.taobao.com', 'www.jd.con', 'www.abc.n', "www.python.org"]
# res = re.match('.*(com|cn|com|n)', 'www.baidu.com')
# print(res.group())
for i in li:
res = re.match("www\.\w*\.(com|cn|net|org)", i)
# 判断
if res:
print(res.group())
else:
print(f'{i}网址有误哦')
# print(i)
2. findall()
python
2. findall()
2.1 作用
以列表形式返回整个字符串中所有匹配到的字符串
2.2 简单使用
# 1.导入模块
import re
# 2. 使用findall()进行匹配操作
# re.findall(pattern, string, flags=0):从头到位匹配,找到所有匹配成功的数据,返回一个列表。如果没有找到匹配的,则返回空列表。
# pattern: 匹配的正则表达式
# string:要匹配的字符串
# flags:标志位,用于控制正则表达式的匹配方式,如是否区分大小写,是否多行匹配等,多数情况下使用不到。
res = re.findall("\d", "123abc!@#123") # 匹配所有数字
print(res) # ['1', '2', '3', '1', '2', '3']
res = re.findall("\w{3}", "pythonth")
print(res) # ['pyt', 'hon']
# 注意:比起match(),findall()更为常用
# 3.sub(正则表达式,新内容,字符串,指定替换的次数) 将匹配到的数据进行替换
# 注意: 正则表达式代表需要被替换的,也就是字符串里面的旧内容
# res = re.sub('python','bingbing','hellopython')
# print(res) #hellobingbing
# res = re.sub('\d','2','这是这个月的第15天')
# print(res) #这是这个月的第22天,没有设置次数默认全部替换
# res = re.sub('\d','2','这是这个月的第15天',1)
# print(res) #这是这个月的第25天
3. 贪婪与非贪婪
python
3. 贪婪与非贪婪
3.1 贪婪匹配:在满足匹配时,匹配尽可能长的字符串(即有多少匹配多少),默认情况下,采用贪婪匹配。
res = re.match('em*','emmmm...') # *修饰的是字符m
print(res.group()) # emmmm
# 默认情况下是贪婪匹配
3.2 非贪婪匹配:在满足匹配时,匹配尽可能短的字符串(即能不匹配就不匹配,按照最少匹配次数进行匹配),使用?来表示非贪婪匹配。
# 在*,+,{m,n}等后面加上?,表示使贪婪变成非贪婪
res = re.match('em*?','emmmm...') # *修饰的是字符m
print(res.group()) # e
# 此时?修饰*,非贪婪时尽可能少的,*匹配前一个字符0个或无限个,?表示匹配前一个字符0个或者1个,所以*取的次数时0次,m的0个是空字符串
res = re.match('em+?','emmmm...')
print(res.group()) # em
# ?修饰+,+匹配前一个字符1次或无限次,?表示匹配前一个字符0次或1次,所以取的次数最少是1次
res = re.match('m*','mmmmm')
print(res.group()) # mmmmm
res = re.match('m*?','mmmmm')
print(res.group()) #
# 字符串是mmmmm,开头匹配m,*最少是0个,所以一个m都没有匹配到。
res = re.match('m{1,5}','mmmmm')
print(res.group()) # mmmmm,默认是贪婪匹配,匹配最多次数5
res = re.match('m{1,5}?','mmmmm')
print(res.group()) # 加上?,非贪婪匹配,匹配最少次数1