python基础语法
一、熟悉python
1. 了解python
Python 是一种高级的、通用的编程语言,它以简洁、易学和可读性强闻名。Python 具有强大的标准库和丰富的第三方库,适用于各种开发任务,如 Web 开发、数据分析、人工智能、科学计算、自动化等领域。Python 被广泛应用于软件开发、系统管理、学术研究等领域。它支持面向对象和函数式编程范式,具有动态类型和自动内存管理的特性。
2. python的特点
1.简洁和易读:Python 采用简洁的语法和清晰的代码风格,使得代码易于编写和阅读,减少了开发时的错误
2.跨平台性:Python 可以在多个操作系统上运行,包括 Windows、Mac 和 Linux,使得开发人员可以在不同的平台上无缝进行开发和部署
3.强大的标准库:Python 内置了大量的库和模块,提供了丰富的功能,例如文件处理、网络通信、数据库连接等,可以极大地提高开发效率
4.大量的第三方库:Python 生态系统非常丰富,拥有众多优秀的第三方库和框架,可以满足各种开发需求,如 Django、NumPy、Pandas、TensorFlow 等
5.动态类型和自动内存管理:Python 是一种动态类型的语言,不需要显式声明变量类型,同时具有自动内存管理机制,减轻了开发者的负担
6.扩展性:Python 可以通过 C/C++ 编写扩展模块,同时也支持与其他编程语言进行交互,如调用 C/C++、Java 等语言的代码
7.多种编程范式支持:Python 支持面向对象编程、函数式编程等多种编程范式,开发者可以根据需要选择适合的编程方式
8.广泛应用领域:Python 在各个领域都有应用,包括 Web 开发、数据科学、人工智能、自动化、网络爬虫等,具有广泛的适用性
3. python的版本
- Python2.X
- Python3.X
二、pycharm编译器
1. 了解pycharm编译器
PyCharm 是一种专业的 Python 集成开发环境(IDE),它由 JetBrains 公司开发并提供。PyCharm 提供了一系列功能和工具,旨在帮助开发者提高 Python 开发效率和质量
2. 编译器的作用
-
代码编辑和调试:PyCharm 提供了强大的代码编辑器,支持代码自动完成、语法检查、代码重构等功能,同时还具备强大的调试功能,可帮助开发者快速排查代码问题
-
项目管理:PyCharm 支持创建和管理多个 Python 项目,可以方便地进行项目配置、依赖管理、模块导入等操作,提高项目组织和管理的效率
-
版本控制:PyCharm 集成了常用的版本控制系统,如 Git、SVN 等,可以直接在 IDE 中进行代码版本管理、冲突解决等操作,方便团队协作开发
-
智能代码分析:PyCharm 内置了智能代码分析功能,可以检测和纠正代码错误、提供代码提示和建议,帮助开发者编写高质量的 Python 代码
-
测试和自动化:PyCharm 支持单元测试和集成测试,可以方便地运行和管理测试用例,同时还提供了自动化测试等功能,帮助开发者确保代码质量和可靠性
-
Web 开发支持:PyCharm 提供了强大的 Web 开发支持,包括 Django 和 Flask 等流行的 Python Web 框架,可以进行 Web 项目开发、调试和测试
3. 安装pycharm
python及pycharm安装教程:https://blog.csdn.net/weixin_43495473/article/details/103559812
三、注释
1、注释是对代码的解释和说明,不会执行,可以增加代码的可执行性
2、python中注释分为两种,一种是单行注释,一种是多行注释
1. 单行注释
只能注释一行
用井号空格来进行注释
# 写入注释***************
也可以使用快捷键 (Ctrl + /)进行注释
2. 多行注释
可以注释多行内容
有两种写法
1、用三对双引号进行括起来
2、用三对单引号进行括起来
"""
第一行注释
第二行注释
第三行注释
"""
'''
第一行注释
第二行注释
第三行注释
'''
四、变量
1. 变量的作用
作⽤: 是⽤来存储数据的(在程序代码中出现的数据,想要保存下来使⽤, 就必须使⽤变量)
注意:变量必须是先定义,再使用
2. 定义变量
变量名 = 数据值 # 可以理解为将 数据值 保存到 变量 中
ege:
name = '张三' # 定义一个变量名为name,存储的数据值就是为 张三
3. 使用变量
变量定义好之后,想要使用变量中的数据,直接使用变量名即可
name = '张三'
print(name)
4. 变量的命名规范
1.第一个字符必须是字母表中字母或下划线 _
2.标识符的其他的部分由字母、数字和下划线组成
3.标识符对大小写敏感
4.不能使用Python关键字命名
建议命名使用驼峰命名法:
1、⼤驼峰: 每个单词的⾸字⺟⼤写 MyName
2、⼩驼峰: 第⼀个单词的⾸字⺟⼩写,其余单词的⾸字⺟⼤写 myName
五、数据类型
认识数据类型:
数据类型是编程语言中用于定义和处理数据的分类或类别。它决定了数据在计算机内存中的存储方式以及对数据进行的操作
数据类型 | 描述 |
---|---|
int(整数) | 表示整数1、2、5 |
String(字符串) | 表示文本数据,用单引号或双引号括起来,如 “Hello, World!” |
bool(布尔) | 表示真假值,只有两个取值,True 和 False |
Tuple(元组) | 表示有序的元素集合,用小括号括起来,元素之间用逗号分隔,如 (1, 2, 3) |
Dictionary(字典) | 表示键值对的集合,用花括号括起来,每个键值对用冒号分隔,键值对之间用逗号分隔,如 {“name”: “Alice”, “age”: 25} |
List(列表) | 表示有序的元素集合,用方括号括起来,元素之间用逗号分隔,如 [1, 2, 3] |
Set(集合) | 表示无序的元素集合,用花括号括起来,元素之间用逗号分隔,如 {1, 2, 3} |
注意:
其中不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)
# 检测数据类型的方法:
type(变量名或数值)
# 想要将这个变量的类型在控制台显示, 需要使⽤ print 输出
print(type(变量))
# 整型 <class 'int'>
age = 18
print(type(age)) # type(age).print 回⻋
# 浮点型 <class 'float'>
height = 1.71
print(type(height))
# 布尔类型 <class 'bool'> True False
isMen = True
print(type(isMen))
# 字符串类型, 使⽤引号引起来的就是字符串 <class 'str'>
name = '⼩明'
No. 23 / 33
print(type(name))
num = '18'
print(type(num)) # str
num = 'True'
print(type(num)) # str
六、数据类型转换
何为数据类型转换:
数据类型转换是将一个数据类型的值转换为另一个数据类型的过程,在编程中,经常需要对数据进行转换以满足特定的需求或操作
什么时候用到数据类型转换:
1、用户输入处理:当用户从键盘或其他输入源输入的数据是字符串类型时,可能需要将其转换为适当的数据类型,以便进行计算、比较或其他操作
2、数据存储和传输:在将数据存储到文件或数据库中,或在网络通信中传输数据时,需要根据特定的需求将数据转换为适当的格式或数据类型
3、数据操作和计算:在进行算术运算、数值计算或逻辑操作时,可能需要将数据转换为相应的数值类型,以便进行正确的计算和处理
4、数据格式化和显示:将数据呈现给用户或以特定的格式输出时,可能需要将数据转换为字符串类型,以便进行格式化、连接或显示5、数据合并和分割:在处理多个数据源或数据集合时,可能需要将不同类型的数据进行合并或拆分,涉及到数据类型转换
python中数据类型分两种:
一种是隐式类型转换 ------ 自动完成
一种是显示类型转换 ------ 需要使用类型函数进行转换
隐式类型转换
如以下示例
num_int = 123 # 代表int整数类型
num_float = 1.23 # 代表float浮点类型
num_new = num_int + num_float # 整数类型和浮点类型相加
print("num_int 数据类型为:",type(num_int))
print("num_float 数据类型为:",type(num_float))
print("num_new 值为:",num_new)
print("num_new 数据类型为:",type(num_new))
结果相加值为浮点类型
num_int 数据类型为: <class 'int'>
num_float 数据类型为: <class 'float'>
num_new 值为: 124.23
num_new 数据类型为: <class 'float'>
显示类型转换
# int():将数据转换为整数类型
x = int(1) # x 输出结果为 1
y = int(2.8) # y 输出结果为 2
z = int("3") # z 输出结果为 3
# float():将数据转换为浮点数类型
x = float(1) # x 输出结果为 1.0
y = float(2.8) # y 输出结果为 2.8
z = float("3") # z 输出结果为 3.0
w = float("4.2") # w 输出结果为 4.2
# str():将数据转换为字符串类型
x = str("s1") # x 输出结果为 's1'
y = str(2) # y 输出结果为 '2'
z = str(3.0) # z 输出结果为 '3.0'
# bool():将数据转换为布尔值类型
bool(0) # 将整数 0 转换为布尔值 False
# tuple():将一个序列转换成元组
list1 = [10, 20, 30]
print(tuple(list1)) # (10, 20, 30)
print(type(tuple(list1))) # <class 'tuple'>
# list() -- 将一个序列转换成列表
t1 = (100, 200, 300)
print(list(t1)) # [100, 200, 300]
print(type(list(t1))) # <class 'list'>
# eval() -- 将字符串中的数据转换成Python表达式原本类型
str1 = '10'
str2 = '[1, 2, 3]'
str3 = '(1000, 2000, 3000)'
print(type(eval(str1))) # <class 'int'>
print(type(eval(str2))) # <class 'list'>
print(type(eval(str3))) # <class 'tuple'>
以下几个内置的函数可以执行数据类型之间的转换。这些函数返回一个新的对象,表示转换的值
函数 | 描述 |
---|---|
int(x [,base]) | 将x转换为一个整数 |
float(x) | 将x转换到一个浮点数 |
complex(real [,imag]) | 创建一个复数 |
str(x) | 将对象 x 转换为字符串 |
repr(x) | 将对象 x 转换为表达式字符串 |
eval(str) | 用来计算在字符串中的有效Python表达式,并返回一个对象 |
tuple(s) | 将序列 s 转换为一个元组 |
list(s) | 将序列 s 转换为一个列表 |
set(s) | 转换为可变集合 |
dict(d) | 创建一个字典。d 必须是一个 (key, value)元组序列。 |
frozenset(s) | 转换为不可变集合 |
chr(x) | 将一个整数转换为一个字符 |
ord(x) | 将一个字符转换为它的整数值 |
hex(x) | 将一个整数转换为一个十六进制字符串 |
oct(x) | 将一个整数转换为一个八进制字符串 |
七、输入与输出
在python中,输入就是获取用户输入键盘的内容
1. 输入的语法
print("提示信息")
变量 = input("提示信息")
2. 输入的特点
- 代码从上到下执行,如果遇到input函数之后,会暂停执行,等待用户输入完成,如果不输入会一直等待
- 输入过程中,如果遇到Enter,会代表这次输入完成
3.会将你输⼊的内容 保存到等号左边的变量中, 并且 变量的数据类型 ⼀定是 str
result = input('请输⼊内容:')
print(type(result), result) # 打印数据类型和 数据值
打印结果
<class 'str'> 你好 世界
3.输出的特点
1、 简单易用:Python提供了简单易懂的输出语法,允许开发者使用print语句或者更先进的print()函数来输出信息。这使得在Python中输出内容变得非常简单
2、自动换行:在默认情况下,print语句或print()函数会在输出完信息后自动换行。这使得输出的内容以清晰的格式呈现,并且易于阅读
3、动态输出:Python允许将变量的值与文本一起输出,同时可以在输出中使用适当的格式化。这使得输出的信息可以动态地根据变量的值进行更新,方便查看程序的执行结果
4、支持多个参数输出:使用print语句或print()函数时,可以同时输出多个参数,它们将以空格分隔。这样可以在一行中输出多个变量或字符串,方便查看或调试程序
5、格式化输出:Python提供了多种格式化输出的方式,如使用字符串拼接、格式化符号(%)以及更强大的字符串格式化方法(如str.format()和f-string),以满足不同输出需求
6、输出重定向:除了在终端窗口中输出信息,Python还支持将输出重定向到文件或其他设备。这对于保存程序的运行结果或将输出导入其他应用程序是很有用的
4.格式化输出
1、使用字符串拼接:可以使用加号(+)将字符串与其他变量或表达式拼接在一起,并输出结果
name = "Alice"
age = 25
print("My name is " + name + " and I am " + str(age) + " years old.")
输出结果
My name is Alice and I am 25 years old.
2、使用百分号(%):使用百分号作为格式化符号,可以在字符串中使用占位符代表需要填入的变量或值。后面的%运算符用于指定实际要填入的值
name = "Alice"
age = 25
print("My name is %s and I am %d years old." % (name, age))
输出结果
My name is Alice and I am 25 years old.
3、使用str.format()方法:str.format()方法允许在字符串中使用花括号{}来指示需要填入的变量或表达式,并使用format()方法传递对应的值
name = "Alice"
age = 25
print("My name is {} and I am {} years old.".format(name, age))
输出结果
My name is Alice and I am 25 years old.
4、使用f-string:f-string是Python3.6及以上版本新增的一种格式化输出方式,它使用花括号内部引用变量,并在字符串前加上字母"f"来表示。在f-string中,可以直接在花括号中引用变量或表达式
name = "Alice"
age = 25
print(f"My name is {name} and I am {age} years old.")
输出结果
My name is Alice and I am 25 years old.
5.快捷方式
1、撤销:CTRL+Z
2、删除一行:CTRL+X
3、复制一行:CTRL+D
八、运算符
1.算数符分类
算数运算符
赋值运算符
复合赋值运算符
比较运算符
逻辑运算符
2.算数运算符
算数符 | 描述 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
// | 整除 |
% | 取余 |
** | 指数 |
() | 小括号 |
3.比较运算符
比较运算符得到的结果都是bool类型
运算符 | 描述 |
---|---|
== | 等于 |
>= | 大于等于 |
<= | 小于等于 |
!= | 不等于 |
> | 大于 |
< | 小于 |
is | 对象标识符比较 |
not | 对象标识符不等 |
a = 5
b = 7
print(a == b) # False
print(a != b) # True
print(a > b) # False
print(a < b) # True
print(a >= b) # False
print(a <= b) # True
x = [1, 2, 3]
y = [1, 2, 3]
z = x
print(x is y) # False
print(x is not y) # True
print(x is z) # True
4.逻辑运算符
运算符 | 描述 |
---|---|
and | 与运算符 |
or | 或运算符 |
not | 非运算符 |
逻辑运算符用于将多个条件进行结合,并返回一个布尔值(True或False)表示运算结果
a = 5
b = 7
c = 3
print(a < b and b < c) # False
print(a < b or b < c) # True
print(not a < b) # False
- "and"运算符:当所有条件都为True时,返回True;只要有一个条件为False,返回False。
- "or"运算符:当至少有一个条件为True时,返回True;所有条件都为False时,返回False。
- "not"运算符:对单个条件进行取反,如果条件为True,返回False;如果条件为False,返回True。
5.赋值运算符
运算符 | 描述 |
---|---|
= | 简单赋值 |
+= | 加法赋值 |
-= | 减法赋值 |
*= | 乘法赋值 |
/= | 除法赋值 |
//= | 取整除赋值 |
%= | 取模赋值 |
**= | 幂运算赋值 |
a = 5
b = 3
# 简单赋值
c = a
print(c) # 5
# 加法赋值
b += a
print(b) # 8
# 减法赋值
b -= a
print(b) # 3
# 乘法赋值
b *= a
print(b) # 15
# 除法赋值
b /= a
print(b) # 3.0
# 取整除赋值
b //= a
print(b) # 0
# 取模赋值
b %= a
print(b) # 0
# 幂运算赋值
b **= a
print(b) # 0
6.运算符的优先级
不用可以去记住运算符的优先级,因为可以使用()来改变优先级
九、条件判断语句
1.if的基本结构
f语句是一种条件语句,它用于根据给定条件的真假来决定是否执行特定的代码块
if 判断条件:
书写条件成立(真),执行的代码
书写条件成立(真),执行的代码
案例:
score = float(input("请输入您的分数:"))
if score >= 90:
print("等级:优秀")
if score >= 80 and score < 90:
print("等级:良好")
if score >= 70 and score < 80:
print("等级:中等")
if score >= 60 and score < 70:
print("等级:及格")
if score < 60:
print("等级:不及格")
在这个案例中,我们使用input()函数获取用户输入的分数,并将输入的字符串转换为浮点数类型(使用float()函数)。然后,使用一系列if语句来判断分数所对应的等级
如果分数大于等于90,则打印"等级:优秀"
如果分数大于等于80且小于90,则打印"等级:良好"
如果分数大于等于70且小于80,则打印"等级:中等"
如果分数大于等于60且小于70,则打印"等级:及格"
如果分数小于60,则打印"等级:不及格"。
2.if-else的基本结构
如果 条件成立 做什么事 否则(条件不成立) 做另一件事
if condition:
# 如果条件为真,执行这里的代码块
# ...
else:
# 如果条件为假,执行这里的代码块
# ...
在if-else语句中,condition是一个需要求值为布尔值(True或False)的表达式或条件。如果condition为True,那么if语句下的代码块将被执行;如果condition为False,那么else语句下的代码块将被执行
x = 5
if x > 0:
print("x是一个正数")
else:
print("x是一个非正数")
在上面的示例中,x > 0是一个条件表达式,它被用作if语句的条件
如果x的值大于0,则条件为True,执行if语句下的代码块,即打印"x是一个正数";
否则,条件为False,执行else语句下的代码块,即打印"x是一个非正数"
3.if elif else 结构
如果某个判断条件有多个, 此时建议使用 if elif else 结构来实现
if condition1:
# 当条件1为真时执行的代码块
# ...
elif condition2:
# 当条件1为假而条件2为真时执行的代码块
# ...
else:
# 当条件1和条件2都为假时执行的代码块
# ...
在if、elif和else结构中,可以根据需要使用多个elif语句,但只能有一个if和一个else。它们的执行顺序是按照从上到下的顺序,只有第一个满足条件的代码块会被执行,其他条件均会被忽略
如果condition1为True,则执行if语句下的代码块
如果condition1为False,并且condition2为True,则执行elif语句下的代码块
如果以上所有条件都为False,则执行else语句下的代码块
案例
x = 5
if x > 10:
print("x大于10")
elif x > 7:
print("x大于7,但小于等于10")
elif x > 3:
print("x大于3,但小于等于7")
else:
print("x不大于3")
在上面的示例中,x的值为5,根据条件的不同,只有第三个elif语句的条件x > 3为真,因此执行对应的代码块,打印"x大于3,但小于等于7"
4.if嵌套基本结构
4.1 什么是if嵌套
if嵌套指的是在一个if语句的代码块内部再嵌套另一个或多个if语句。通过嵌套if语句,我们可以根据多个条件进行更复杂的判断和分支选择
4.2 什么时候用到if嵌套
-
多个条件的逻辑判断:当需要根据多个条件的组合进行判断时,可以使用if嵌套来实现。通过嵌套的if语句,可以根据每个条件的满足与否执行对应的代码块
-
多层次的分支选择:有时候,分支选择可以有多个层次,每个层次都有自己的条件和执行代码。使用if嵌套,可以根据条件的满足情况,逐层选择执行对应的代码块
-
特殊条件的处理:有些条件可能是特殊情况,需要在某个条件成立的前提下再进行更详细的判断。通过if嵌套,可以先判断特殊条件,再根据不同的情况进行更深层次的判断和处理
4.3 基本语法
if condition1:
# 如果条件1满足,则执行下面的代码块1
# ...
if condition2:
# 如果条件2满足,则执行下面的代码块2
# ...
elif condition3:
# 如果条件1满足而条件2不满足且条件3满足,则执行下面的代码块3
# ...
else:
# 如果以上所有条件都不满足,则执行下面的代码块4
# ...
else:
# 如果条件1不满足,则执行下面的代码块5
# ...
在这个语法结构中,我们可以在if代码块内部嵌套一个或多个if语句。嵌套的if语句可以有自己的elif和else分支。条件表达式可以是任意合法的布尔表达式,用于判断是否满足特定条件
4.4 案例
x = 10
y = 5
if x > y:
print("x大于y")
if x > 0:
print("x大于0")
else:
print("x小于等于0")
else:
print("x小于等于y")
在这个例子中
①首先使用if判断x是否大于y
如果条件为真,则打印"x大于y"
然后进一步进行if嵌套判断
②如果x大于0,则打印"x大于0"
否则,即x小于等于0,则打印"x小于等于0"
③如果x不大于y,则直接打印"x小于等于y"
# 运行结果
x大于y
x大于0
1、判断一个年份是否为闰年
year = 2023
if year % 4 == 0:
if year % 100 == 0:
if year % 400 == 0:
print("闰年")
else:
print("平年")
else:
print("闰年")
else:
print("平年")
2、根据用户的购买金额和会员等级计算折扣和积分
解析案例
首先,根据购买金额是否大于等于1000来判断是否满足享受折扣的条件
如果购买金额大于等于1000,则进入if语句内部,根据会员等级来确定不同的折扣和积分计算规则
如果会员等级是"Gold",则折扣为20%,根据每10元积1分的规则计算积分
如果会员等级是"Silver",则折扣为15%,根据每20元积1分的规则计算积分
如果会员等级不是"Gold"或"Silver",则折扣为10%,根据每30元积1分的规则计算积分
如果购买金额小于1000,则不享受折扣,折扣为0,并根据每50元积1分的规则计算积分
计算实际应付金额时,将折扣应用于购买金额,得到最终的应付金额
打印出折扣、应付金额和积分的结果
amount = 1200
membership_level = "Gold"
if amount >= 1000:
if membership_level == "Gold":
discount = 0.2 # 20% 折扣
points = amount // 10 # 每10元积1分
elif membership_level == "Silver":
discount = 0.15 # 15% 折扣
points = amount // 20 # 每20元积1分
else:
discount = 0.1 # 10% 折扣
points = amount // 30 # 每30元积1分
else:
discount = 0
points = amount // 50 # 每50元积1分
total_price = amount * (1 - discount)
print(f"折扣:{discount * 100}%")
print(f"应付金额:{total_price}")
print(f"积分:{points}")
输出结果
折扣:20.0%
应付金额:960.0
积分:120
3、根据用户的年龄和职业,判断是否符合借款条件
案例解析
首先,根据年龄是否大于等于18来判断是否满足借款条件
如果年龄满足条件,则进入if语句内部,根据职业类型来确定不同的借款金额和利率规则
如果职业是"Engineer"或"Doctor",同时年龄小于等于40,那么借款金额为100万,利率为5%
如果职业是"Engineer"或"Doctor",但年龄大于40,那么借款金额为50万,利率为8%
如果职业是"Teacher",同时年龄小于等于35,那么借款金额为50万,利率为6%
如果职业是"Teacher",但年龄大于35,那么借款金额为30万,利率为10%
如果职业不是"Engineer"、“Doctor"或"Teacher”,那么借款金额为20万,利率为12%
如果年龄不满足条件,则借款金额和利率都为0,同时打印出"未满足借款条件"的提示
打印出借款金额和利率的结果
age = 30
occupation = "Engineer"
if age >= 18:
if occupation == "Engineer" or occupation == "Doctor":
if age <= 40:
loan_amount = 1000000
interest_rate = 0.05
else:
loan_amount = 500000
interest_rate = 0.08
elif occupation == "Teacher":
if age <= 35:
loan_amount = 500000
interest_rate = 0.06
else:
loan_amount = 300000
interest_rate = 0.1
else:
loan_amount = 200000
interest_rate = 0.12
else:
loan_amount = 0
interest_rate = 0
print("未满足借款条件")
print(f"借款金额:{loan_amount}")
print(f"利率:{interest_rate * 100}%")
输出结果
借款金额:1000000
利率:5.0%
十、循环
1.何为循环
程序开发中(写代码), 有三大流程(三大结构):
1, 顺序, 代码从上到下,全部执行
2, 分支, 判断语句,代码有选择性的执行
3, 循环, 重复执行某一部分的代码
2.循环的作用
是让 指定的代码 重复的执行
3.循环的分类
在Python中,循环分为while
和for
两种,最终实现效果相同
4.while的基本语法
while condition:
# 在条件为True时执行的代码块
total = 0
num = 1
while num <= 5:
total += num
num += 1
print(total) # 输出结果为 15
案例
# 初始化一个空列表
numbers = []
# 提示用户输入数字,直到用户输入"done"时结束循环
while True:
user_input = input("请输入数字(输入'done'结束): ")
# 检查用户输入是否为'done',如果是则跳出循环
if user_input == "done":
break
# 检查用户输入的是否为有效数字,如果不是则继续循环
try:
number = float(user_input)
except ValueError:
print("无效的数字,请重新输入")
continue
# 将有效的数字添加到列表中
numbers.append(number)
# 计算列表中数字的平均值
total = sum(numbers)
average = total / len(numbers)
# 输出结果
print("输入的数字列表:", numbers)
print("平均值:", average)
案例解析
循环条件为True,所以循环会一直执行下去
在每次循环开始时,我们通过input函数获取用户的输入
如果用户输入的是"done",则使用break语句跳出循环
如果用户输入的是一个有效的数字,我们将其转换为浮点数,并将其添加到列表中
如果用户输入的不是一个有效的数字,我们会输出错误提示信息,并使用continue语句跳过本次循环的剩余代码
5.break和continue
5.1 break实例
break 语句用于中断当前所在的循环,跳出整个循环结构,继续执行循环外部的代码
while True:
user_input = input("请输入数字:")
if user_input == "quit":
break
print("输入的数字是:" + user_input)
5.2 continue实例
continue 语句用于跳过当前循环的剩余代码,进入下一次循环的迭代
for i in range(1, 6):
if i == 3:
continue
print(i)
6.while循环嵌套
当需要处理更复杂的问题或执行多个层次的循环时,可以使用嵌套的 while 循环。嵌套的 while 循环意味着一个 while 循环位于另一个 while 循环内部。这样可以灵活地控制程序的流程和逻辑
row = 1
while row <= 3:
col = 1
while col <= 5:
print(row, col)
col += 1
row += 1
在这个示例中,外层的 while 循环控制变量 row 的范围,内层的 while 循环控制变量 col 的范围。在每次外层循环执行时,内层循环会完整地执行完毕,然后外层循环再执行下一次迭代
输出结果
1 1
1 2
1 3
1 4
1 5
2 1
2 2
2 3
2 4
2 5
3 1
3 2
3 3
3 4
3 5
在该示例中,外层循环从 1 到 3,内层循环从 1 到 5。内层循环的代码块会打印当前的行和列数(row 和 col),通过内外层循环的交替迭代,最终打印出了所有的组合
7.for循环
for循环是一种常见的循环结构,用于在给定的序列(如列表、字符串、元组等)上进行迭代。for循环会遍历序列中的每个元素,并执行指定的操作
基本语法:
for item in sequence:
# 在每次迭代中执行的操作
item是一个变量,它在每次迭代时代表序列中的当前元素
sequence是要进行迭代的序列,可以是列表、字符串、元组或其他可迭代对象
在循环体内,可以执行一系列操作来处理当前元素,这些操作将为序列中的每个元素执行一次
案例
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
输出结果
apple
banana
cherry
8.range函数
range() 函数是 Python 中常用的内置函数,用于生成一个整数序列。它常用于循环结构中,配合 for 循环一起使用
基本语法
range(start, stop, step)
- start:可选参数,表示序列的起始值,默认为 0
- stop:必选参数,表示序列的结束值(不包含该值)
- step:可选参数,表示序列中的元素之间的间隔,默认为 1
range() 函数返回一个可迭代对象,可以通过 list() 函数将其转换为列表
# 生成 0 到 4 的序列
print(list(range(5))) # [0, 1, 2, 3, 4]
# 生成 1 到 10(不包含 10)的序列
print(list(range(1, 10))) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 生成 2 到 10(不包含 10),步长为 2 的序列
print(list(range(2, 10, 2))) # [2, 4, 6, 8]
在循环结构中,我们可以使用 range() 结合 for 循环来遍历整数序列
for i in range(5):
print(i)
输出结果
0
1
2
3
4
以上代码将会遍历 range(5) 生成的整数序列,将每个元素赋值给变量 i,然后打印出来。通过 range() 函数,我们可以方便地生成指定范围和步长的整数序列,用于循环迭代和其他应用场景
十一、字符串
1. 认识字符串
字符串是容器,因为字符串中可以包含多个字符
a = 'hello world'
b = "abcdefg"
print(type(a))
print(type(b))
2. 字符串的定义
字符串可以用单引号 (‘’) 或双引号 (“”) 括起来定义
my_string = 'Hello, World!'
my_string = "Hello, World!"
3. 访问字符串的字符(下标)
可以使用索引操作符 [] 来访问指定位置的字符。需要注意的是,字符串的索引从 0 开始
my_string = "Hello, World!"
print(my_string[0]) # 输出:H
修改元素:尽管字符串是不可变的数据类型,但可以创建一个新的字符串来替换指定位置的字符,实现间接的修改操作
my_list = [1, 2, 3, 4]
my_list[2] = 5 # 将第三个元素修改为5
print(my_list) # 输出:[1, 2, 5, 4]
负数下标:除了正数下标,还可以使用负数下标来访问序列中的元素,负数下标从末尾开始计数,即 -1 表示倒数第一个元素,-2 表示倒数第二个元素,以此类推
my_string = "Hello, World!"
print(my_string[-1]) # 输出:!
越界错误:应注意避免使用越界的下标,即超出序列长度的下标。如果使用了越界的下标,将会引发 IndexError 错误
my_list = [1, 2, 3]
print(my_list[3]) # IndexError: list index out of range
4. 字符串切片
使用切片操作符 [start:stop:step] 可以获取字符串的子串
start(可选):切片的起始位置,默认为序列的开头
stop(必选):切片的结束位置(不包含该位置的元素),默认为序列的结尾
step(可选):切片的步长,表示每次取元素的间隔,默认为 1
my_string = "Hello, World!"
print(my_string[7:12]) # 输出:World
my_string = "Hello, World!"
# 获取从索引 7 开始到末尾的子串
print(my_string[7:]) # 输出:World!
# 获取从索引 0 到 5 的子串(不包含索引 5)
print(my_string[:5]) # 输出:Hello
# 获取从索引 0 到 5 的子串,并以步长为 2 获取间隔的字符
print(my_string[::2]) # 输出:HloWrd
# 使用负数索引,获取倒序的子串(从末尾开始)
print(my_string[::-1]) # 输出:!dlroW ,olleH
5. 字符串拼接
使用加号 (+) 可以将多个字符串拼接在一起
name = "Alice"
greeting = "Hello, " + name
print(greeting) # 输出:Hello, Alice
6. 字符串长度
使用
len()
函数可以获取字符串的长度(字符个数)
my_string = "Hello, World!"
print(len(my_string)) # 输出:13
7. 字符串格式化
使用字符串的
format() 方法
可以进行字符串格式化操作,将变量的值插入到字符串中
age = 25
message = "I am {} years old.".format(age)
print(message) # 输出:I am 25 years old.
或者使用
f-string
进行更简洁的字符串格式化
message = f"I am {age} years old."
print(message) # 输出:I am 25 years old.
8. 字符串的查找
在字符串中查找特定子字符串或字符可以使用多种方法。下面介绍几种常用的字符串查找方法
find() 方法
:
find()
方法返回子字符串在原字符串中第一次出现的索引,如果找不到则返回 -1
my_string = "Hello, World!"
index = my_string.find("World")
print(index) # 输出:7
index() 方法
:
index()
方法与find()
方法类似,也返回子字符串在原字符串中第一次出现的索引,但如果找不到则会引发 ValueError 错误
my_string = "Hello, World!"
index = my_string.index("World")
print(index) # 输出:7
startswith()
和endswith()
方法:
startswith()
方法用于检查字符串是否以指定的子字符串开头,返回布尔值。
endswith()
方法用于检查字符串是否以指定的子字符串结尾,也返回布尔值
my_string = "Hello, World!"
print(my_string.startswith("Hello")) # 输出:True
print(my_string.endswith("World!")) # 输出:True
正则表达式查找:
使用 re 模块可以进行更复杂的模式匹配查找操作,支持正则表达式的灵活匹配规则
import re
my_string = "Hello, World!"
matches = re.findall(r"o", my_string)
print(matches) # 输出:['o', 'o']
9. 字符串的替换方法replace
基本语法
new_string = str.replace(old, new [, count])
str 是原始字符串,即调用该方法的字符串
old 是要被替换的子串
new 是用于替换的新字符串
count 是可选参数,指定最多替换的次数
my_string = "Hello, World!"
# 将字符串中的 "World" 替换为 "Python"
new_string = my_string.replace("World", "Python")
print(new_string) # 输出:Hello, Python!
# 替换所有的 "o" 为 "X"
new_string = my_string.replace("o", "X")
print(new_string) # 输出:HellX, WXRld!
# 替换最多两次的 "o" 为 "X"
new_string = my_string.replace("o", "X", 2)
print(new_string) # 输出:HellX, WXRld!
10. 字符串的链接join
在 Python 中,可以使用字符串的
join()
方法将多个字符串连接起来形成一个新的字符串。该方法接收一个可迭代的对象作为参数,如列表、元组等,然后将它们的元素按照指定的连接符进行连接
# 语法:
new_string = connector.join(iterable)
connector 是连接符,用于将元素连接在一起
iterable 是可迭代的对象,其中的元素将被连接在一起
words = ["Hello", "World", "!"]
# 使用空格连接列表中的字符串
new_string = " ".join(words)
print(new_string) # 输出:Hello World !
# 使用逗号和空格连接列表中的字符串
new_string = ", ".join(words)
print(new_string) # 输出:Hello, World, !
# 使用连接符进行连接
new_string = "-".join(words)
print(new_string) # 输出:Hello-World-!
十二、列表
列表(List)是 Python 中最常用的数据结构之一,它是一个有序、可变、可重复的容器,可以存储任意类型的元素
1. 创建列表
可以使用
方括号 []
或者list()
函数来创建一个空列表,也可以在创建时直接初始化元素
empty_list = []
numbers = [1, 2, 3, 4, 5]
mixed_list = [1, "two", 3.0, [4, 5]]
2. 访问元素
使用下标(索引)可以访问列表中的特定元素,下标从 0 开始。还可以使用负数下标从列表末尾开始访问
my_list = [10, 20, 30, 40, 50]
print(my_list[0]) # 输出:10
print(my_list[-1]) # 输出:50
3. 修改元素
列表中的元素是可变的,可以通过下标对其进行修改
my_list = [10, 20, 30, 40, 50]
my_list[1] = 25
print(my_list) # 输出:[10, 25, 30, 40, 50]
4. 迭代访问
使用循环可以迭代访问列表中的每一个元素
my_list = [10, 20, 30, 40, 50]
for num in my_list:
print(num)
5. 添加元素
append(element)
:
该方法用于在列表的末尾添加一个元素。它只接受一个参数,即要添加的元素
my_list = [1, 2, 3]
my_list.append(4)
print(my_list) # 输出:[1, 2, 3, 4]
6. 插入元素
insert(index, element)
:
insert()
方法可以在列表的指定位置插入一个元素。第一个参数是要插入的位置(索引),第二个参数是要插入的元素
my_list = [1, 2, 3]
my_list.insert(1, 4)
print(my_list) # 输出:[1, 4, 2, 3]
7. 删除元素
remove(element)
:
remove()
方法用于从列表中移除指定的元素。如果列表中有多个相同的元素,只会移除第一个匹配的元素
my_list = [1, 2, 3, 2]
my_list.remove(2)
print(my_list) # 输出:[1, 3, 2]
8. 移除元素
pop([index])
:
pop()
方法用于移除并返回列表中指定位置的元素。如果不指定位置,默认移除并返回最后一个元素
my_list = [1, 2, 3]
popped_element = my_list.pop(1)
print(popped_element) # 输出:2
print(my_list) # 输出:[1, 3]
9. 获取元素长度
len(list)
:
len()
函数用于获取列表的长度,即列表中元素的个数
my_list = [1, 2, 3, 4, 5]
length = len(my_list)
print(length) # 输出:5
10. 列表的反转
列表有一个
reverse()
方法,可以用于反转列表中的元素顺序。该方法会修改原始列表,而不是创建一个新的反转后的列表
my_list = [1, 2, 3, 4, 5]
my_list.reverse()
print(my_list) # 输出:[5, 4, 3, 2, 1]
如果你希望创建一个反转后的新列表而不改变原始列表,可以使用切片(slice)操作符
my_list = [1, 2, 3, 4, 5]
reversed_list = my_list[::-1]
print(reversed_list) # 输出:[5, 4, 3, 2, 1]
11. 列表的复制
将列表中的数据复制⼀份,给到⼀个新的列表
使⽤场景: 有⼀个列表, 需要修改操作列表中的数据, 修改之后, 需要和原数据进⾏对⽐,即原数据不能改
使⽤切⽚
变量 = 列表[:]
my_list = [1, 2, 3]
my_list1 = my_list[:]
print('my_list :', my_list)
print('my_list1:', my_list1)
my_list1[1] = 22
print('my_list :', my_list)
print('my_list1:', my_list1)
print('-' * 30)
使⽤ copy ⽅法
变量 = 列表.copy()
my_list = [1, 2, 3]
my_list2 = my_list.copy()
print('my_list :', my_list)
print('my_list2:', my_list2)
my_list2[2] = 33
print('my_list :', my_list)
print('my_list2:', my_list2)
12. 列表的排序
列表的排序, ⼀般来说都是对数字进⾏排序的
列表.sort() # 按照升序排序, 从⼩到⼤
列表.sort(reverse=True) # 降序排序, 从⼤到⼩
my_list = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
# 升序排序
my_list.sort()
print(my_list)
# 降序排序
my_list.sort(reverse=True)
print(my_list)
13. 列表的嵌套
列表嵌套, 列表中的内容还是列表
使⽤下标来确定获取的是什么类型的数据,然后确定可以继续进⾏什么操作
person_info = [["张三", "18", "功能测试"], ["李四",
"20", "⾃动化测试"]]
print(len(person_info)) # 2
print(person_info[0]) # ['张三', '18', '功能测试']
print(person_info[0][0]) # '张三'
print(person_info[0][0][0]) # 张
# 将 18 改为 19
person_info[0][1] = '19'
print(person_info) # [['张三', '19', '功能测试'],
['李四', '20', '⾃动化测试']]
# 给 李四 所在的列表添加⼀个性别 信息
person_info[1].append('男')
print(person_info) # [['张三', '19', '功能测试'],
['李四', '20', '⾃动化测试', '男']]
# 将张三的年龄信息删除
# person_info[0].pop(1)
person_info[0].remove('19')
print(person_info) # [['张三', '功能测试'], ['李四',
'20', '⾃动化测试', '男']]
14. 列表去重
列表去重:列表中存在多个数据, 需求, 去除列表中重复的数据.
⽅式1. 思路
遍历原列表中的数据判断在新列表中是否存在, 如果存在,不管,
如果不存在放⼊新的列表中
遍历: for 循环实现
判断是否存在: 可以 使⽤ in
存⼊数据: append()
my_list = [1, 2, 2, 3, 3, 4, 5, 5]
unique_list = []
for x in my_list:
if x not in unique_list:
unique_list.append(x)
print(unique_list) # 输出:[1, 2, 3, 4, 5]
使用 set:
将列表转换为集合(set)是一种简单的方法,因为集合中不允许重复的元素。然后,将集合转换回列表即可
my_list = [1, 2, 2, 3, 3, 4, 5, 5]
unique_list = list(set(my_list))
print(unique_list) # 输出:[1, 2, 3, 4, 5]
使用列表推导式(list comprehension):
利用列表推导式可以创建一个新列表,其中不包含重复的元素。遍历原始列表,只添加未在新列表中出现过的元素
my_list = [1, 2, 2, 3, 3, 4, 5, 5]
unique_list = [x for i, x in enumerate(my_list) if x not in my_list[:i]]
print(unique_list) # 输出:[1, 2, 3, 4, 5]
十三、元组
元组(Tuple)是 Python 中的一种数据类型,类似于列表,用于存储多个数据项。与列表不同的是,元组是不可变的,即创建后就不能修改其中的元素
1. 定义元组
定义元组:
元组使用圆括号 ()
来定义,其中的元素可以是任意类型,并且用逗号 , 分隔
my_tuple = (1, 2, 3, "apple", "banana")
2. 访问元组
可以使用索引来访问元组中的特定元素,索引从 0 开始
my_tuple = (1, 2, 3, "apple", "banana")
print(my_tuple[0]) # 输出:1
3. 切片元组
类似于列表,可以使用
切片操作符 [:]
进行元组的切片操作,以获取指定的子元组
my_tuple = (1, 2, 3, "apple", "banana")
print(my_tuple[2:4]) # 输出:(3, "apple")
4. 统计元组中的元素
count(value)
:统计元组中指定元素出现的次数
my_tuple = (1, 2, 2, 3, 3, 3)
count = my_tuple.count(2)
print(count) # 输出:2
5. index返回位置
index(value)
:返回元组中第一个匹配元素的索引位置
my_tuple = (1, 2, 2, 3, 3, 3)
index = my_tuple.index(3)
print(index) # 输出:3
6. 元组的不变性
元组是不可变的,一旦创建,就不能修改其中的元素。这意味着无法对元组进行添加、删除或修改操作
my_tuple = (1, 2, 3)
my_tuple[0] = 4 # 会引发 TypeError
十四、字典
字典(Dictionary)是 Python 中一种常用的数据结构,用于存储键-值对(key-value pairs)。字典是可变的,可以动态地添加、修改和删除键值对
- 字典 dict, 字典中的数据是由键(key)值(value)对组成的
(键表示数据的名字, 值就是具体的数据) - 在字典中⼀组键值对是⼀个数据, 多个键值对之间使⽤ 逗号
隔开变量 = {key: value, key:value, …} - ⼀个字典中的键是唯⼀的,不能重复的, 值可以是任意数据
- 字典中的键 ⼀般都是 字符串,可以是数字, 不能是列表
1. 定义字典
字典使用
花括号 {}
来定义,键值对使用冒号 : 分隔,多个键值对之间用逗号 , 分隔
my_dict = {"name": "Alice", "age": 25, "country": "USA"}
2. 访问元素
可以使用键来访问字典中的特定值。如果键存在,则返回对应的值;如果键不存在,则会引发 KeyError 错误
my_dict = {"name": "Alice", "age": 25, "country": "USA"}
print(my_dict["name"]) # 输出:Alice
3. 添加或修改键值对
可以通过指定键值对的方式向字典中添加新的键值对,或者修改已存在的键值对
my_dict = {"name": "Alice", "age": 25}
my_dict["country"] = "USA" # 添加新键值对
my_dict["age"] = 26 # 修改已有键对应的值
4. 删除键值对
使用
del 关键字
可以删除字典中的特定键值对
my_dict = {"name": "Alice", "age": 25, "country": "USA"}
del my_dict["age"] # 删除键为 "age" 的键值对
5. 字典的常用方法
- keys() 返回字典中所有的键
- values() 返回字典中所有的值
- items() 返回字典中所有的键值对
my_dict = {"name": "Alice", "age": 25, "country": "USA"}
keys = my_dict.keys()
values = my_dict.values()
items = my_dict.items()
- 遍历键
my_dict = {"name": "Alice", "age": 25, "country": "USA"}
for key in my_dict.keys():
print(key)
- 遍历值
my_dict = {"name": "Alice", "age": 25, "country": "USA"}
for value in my_dict.values():
print(value)
- 遍历键值对
my_dict = {"name": "Alice", "age": 25, "country": "USA"}
for key, value in my_dict.items():
print(key, value)
十五、集合
集合(Set)是 Python 中的一种无序、可变的数据类型,用于存储不重复的元素。集合中的元素是唯一的,不会重复出现
1. 定义集合
集合使用花括号 {} 来定义,元素之间用逗号 , 分隔
my_set = {1, 2, 3, 4, 5}
2. 添加元素
可以使用
add()
方法向集合中添加新的元素
如果添加的元素已经存在于集合中,则不会产生任何变化
my_set = {1, 2, 3}
my_set.add(4)
3. 移除元素
可以使用 remove() 方法从集合中移除指定的元素。如果要移除的元素不存在于集合中,则会引发 KeyError 错误。如果不希望引发错误,可以使用 discard() 方法
my_set = {1, 2, 3}
my_set.remove(2)
> 在 Python 中,可以使用 def 关键字来定义函数
my_set = {10, 20}
my_set.discard(10)
print(my_set)
my_set.discard(10)
print(my_set)
4. 遍历集合
可以使用
for
循环遍历集合中的每个元素。集合是无序的,所以遍历结果的顺序是不确定的
my_set = {1, 2, 3}
for element in my_set:
print(element)
十六、推导式
1. 列表推导式
列表推导式(List Comprehension)是一种在 Python 中用简洁的语法生成新的列表的方法。它可以通过对一个可迭代对象进行遍历,并在每次迭代时应用一个表达式来创建新的列表
[expression for item in iterable]
- expression 是应用于每个 item 的表达式
- item 是可迭代对象 iterable 中的每个元素
# 创建平方数列表
squared_numbers = [x**2 for x in range(1, 6)]
# 输出结果
print(squared_numbers) # [1, 4, 9, 16, 25]
- 在上述例子中,使用列表推导式 [x**2 for x in range(1, 6)] 创建了一个平方数的列表
- 在这个列表推导式中,range(1, 6) 产生一个包含 1 到 5 的迭代器
- 而 x**2 是应用于每个迭代元素的表达式
- 得到的结果就是该元素的平方数
- 最后,将所有平方数组成的列表赋值给变量 squared_numbers
2. 字典推导式
字典推导式(Dictionary Comprehension)是一种在 Python 中用简洁的语法生成新字典的方法。它类似于列表推导式,可以通过对一个可迭代对象进行遍历,并在每次迭代时应用一个表达式来创建新的字典
{key_expression: value_expression for item in iterable}
- key_expression 是将应用于每个 item 的表达式,用于生成字典中的键
- 而 value_expression 是将应用于每个 item 的表达式,用于生成字典中的值
# 创建字符串长度字典
strings = ["apple", "banana", "orange"]
length_dict = {s: len(s) for s in strings}
# 输出结果
print(length_dict) # {'apple': 5, 'banana': 6, 'orange': 6}
- 在上述例子中,使用字典推导式 {s: len(s) for s in strings} 创建了一个将字符串列表中的元素作为键,长度作为值的字典
- 在字典推导式中,for s in strings 表示对字符串列表中的每个元素进行迭代
- 而 s: len(s) 则表示将每个元素作为键 s,并将其长度作为值 len(s)
3. 集合推导式
集合推导式(Set Comprehension)是一种在 Python 中用简洁的语法生成新的集合的方法。它类似于列表推导式和字典推导式,可以通过对一个可迭代对象进行遍历,并在每次迭代时应用一个表达式来创建新的集合
{expression for item in iterable}
- expression 是将应用于每个 item 的表达式,用于生成集合中的元素
# 创建不重复字符集合
strings = ["apple", "banana", "orange"]
unique_chars = {char for s in strings for char in s}
# 输出结果
print(unique_chars) # {'p', 'l', 'n', 'g', 'e', 'o', 'b', 'r', 'a'}
- 在上述例子中,使用集合推导式 {char for s in strings for char in s} 创建了一个集合
- 其中包含了字符串列表中所有不重复的字符
- 在集合推导式中,for s in strings 表示对字符串列表中的每个元素进行迭代
- 而 for char in s 则表示对每个字符串中的字符进行迭代。
- 最后,将所有字符组成的集合赋值给变量 unique_chars
4. 元组推导式
元组推导式可以利用 range 区间、元组、列表、字典和集合等数据类型,快速生成一个满足指定需求的元组
(expression for item in Sequence )
或
(expression for item in Sequence if conditional )
# 创建数字元组
numbers = (x for x in range(1, 6))
# 输出结果
print(tuple(numbers)) # (1, 2, 3, 4, 5)
十七、函数
函数是一段封装了特定功能的可重复使用的代码块。它可以接收输入参数(也称为参数或参数)并执行一系列操作,然后返回一个输出结果(也称为返回值)
1. 函数的定义
在 Python 中,可以使用 def 关键字来定义函数
def function_name(parameters):
"""
Docstring - 函数的文档字符串,可选
"""
# 函数体 - 包含实现函数功能的代码块
statements
return value # 可选,用于指定函数的返回值
- def 是定义函数的关键字
- function_name 是函数的名称,遵循命名规则(建议使用小写字母和下划线的组合)
- parameters 是函数的参数列表,用于接收传递给函数的值。参数可以有默认值,也可以没有
- “”“Docstring”“” 是可选的函数文档字符串,用于描述函数的目的、功能和使用方法等
- statements 是函数体,包含实现函数功能的代码块。函数体内可以执行一系列操作
- return value 是可选的 return 语句,用于指定函数返回的值。如果没有 return 语句或只有 return 而没有返回值,函数默认返回 None
案例
def greet(name):
"""
打印问候语
"""
print("Hello, " + name + "!")
# 调用函数
greet("Alice")
在上述例子中
greet 是函数的名称,它接受一个参数 name
函数体中的 print 语句会根据传入的参数打印相应的问候语
通过调用 greet 函数并传递参数 “Alice”
会打印出 “Hello, Alice!”
2. 函数的调用
function_name(arguments)
function_name
是要调用的函数的名称,遵循函数定义时的命名规则arguments
是调用函数时传递给函数的参数值,可以是零个或多个参数,多个参数之间用逗号 , 分隔
在调用函数时,可以省略参数的默认值,如果函数定义中有默认值的参数,可以根据需要选择性地传递参数(缺省参数)
def greet(name, greeting="Hello"):
"""
打印问候语
"""
print(greeting + ", " + name + "!")
# 调用函数,省略参数的默认值
greet("Alice") # 输出 "Hello, Alice!"
# 调用函数,并传递参数覆盖默认值
greet("Alice", "Hi") # 输出 "Hi, Alice!"
- 在上述例子中,函数 greet 接受两个参数:name 和 greeting
- greeting 参数具有默认值 “Hello”
- 在第一个函数调用中,省略了 greeting 参数,使用了默认值,输出 “Hello, Alice!”
- 在第二个函数调用中,显式地传递了 “Hi” 作为 greeting 参数的值,输出 “Hi, Alice!”
3. 文档注释
⽂档注释的本质,还是注释, 只不过书写的位置和作⽤⽐较特殊
- 书写位置, 在函数名的下⽅使⽤ 三对双引号进⾏的注释
- 作⽤: 告诉别⼈这个函数如何使⽤的, ⼲什么的
- 查看, 在调⽤的时候, 将光标放到函数名上,使⽤快捷键
Ctrl q(Windows)
Mac(ctrl j)
ctrl(cmd) B 转到函数声明中查看(按住Ctrl(cmd) ⿏标左键点击)
4. 函数的嵌套使用
在⼀个函数定义中调⽤另⼀个函数
- 函数定义不会执⾏函数体中的代码
- 函数调⽤会执⾏函数体中的代码
- 函数体中代码执⾏结束会回到函数被调⽤的地⽅继续向下执⾏
def func1():
print(1)
print('func1')
print(2)
def func2():
print(3)
func1()
print(4)
print(5)
func2()
print(6)
# 5 3 1 2 4 6
5. 函数的参数
函数的参数是在函数定义中声明的变量,用于接收外部传递给函数的值。参数允许我们向函数内部传递数据,以在函数执行时使用这些数据
# 1. 定义⼀个函数, my_sum ,对两个数字进⾏求和计算.
def my_sum():
num1 = 10
num2 = 20
num = num1 + num2
print(num)
my_sum()
1、位置参数
位置参数是按照它们在函数参数列表中的顺序进行传递的参数。当调用函数时,必须按照定义的顺序传递对应的参数值
def add(x, y):
"""
计算两个数的和
"""
return x + y
# 调用函数,传递位置参数
result = add(2, 3) # 结果为 5
2、关键字参数
关键字参数通过参数名来指定参数的值,这样可以不用考虑参数的顺序。通过指定参数名,可以跳过某些可选参数或指定参数的值
def add(x, y):
"""
计算两个数的和
"""
return x + y
# 调用函数,传递关键字参数
result = add(x=2, y=3) # 结果为 5
result = add(y=3, x=2) # 结果为 5,参数的顺序无关紧要
3、默认参数(缺省参数)
默认参数在函数定义时为参数指定默认值。如果在函数调用时没有传递对应的参数值,则使用默认值
def say_hello(name="Guest"):
"""
打印问候语
"""
print("Hello, " + name + "!")
# 调用函数,使用默认参数
say_hello() # 输出 "Hello, Guest!"
say_hello("Alice") # 输出 "Hello, Alice!"
4、可变参数(不定长参数)
可变参数允许函数接受任意数量的参数。在函数定义时,可以使用 *args 接收多个位置参数或使用 **kwargs 接收多个关键字参数
def add(*args):
"""
计算多个数的和
"""
result = 0
for num in args:
result += num
return result
# 调用函数,传递可变数量的位置参数
result = add(2, 3, 4, 5) # 结果为 14
6. 函数的返回值
函数的返回值是函数执行完毕后,返回给调用方的结果。通过返回值,函数可以将计算结果、处理结果或其他需要传递给调用方的数据返回出来
在 Python 中,使用 return 语句来指定函数的返回值。函数可以返回一个值,也可以返回多个值。如果函数没有指定返回值,它将默认返回 None
def add(x, y):
"""
计算两个数的和
"""
return x + y
# 调用函数,并接收返回值
result = add(2, 3)
print(result) # 输出 5
- 在上述例子中,add 函数计算两个数的和,并使用 return 语句返回结果
- 通过调用 add(2, 3) 并将返回值赋给变量 result
- 可以获取函数的返回结果,并将其打印出来
def get_name_and_age():
"""
获取姓名和年龄
"""
name = "Alice"
age = 25
return name, age
# 调用函数,并接收多个返回值
name, age = get_name_and_age()
print(name) # 输出 "Alice"
print(age) # 输出 25
- 在上述例子中,get_name_and_age 函数返回姓名和年龄两个值
- 通过调用该函数,并使用多个变量接收返回值
- 可以按照顺序获取每个返回值,并将其打印出来
def greet(name):
"""
打印问候语
"""
print("Hello, " + name + "!")
# 调用函数
result = greet("Alice") # 输出 "Hello, Alice!"
print(result) # 输出 None
- 在上述例子中,greet 函数没有指定返回值,所以默认返回 None
- 通过调用 greet(“Alice”),可以打印出问候语
- 但变量 result 接收到的是 None
7. 组包与拆包
组包(pack): 将多个数据值使⽤逗号连接, 组成元组
拆包(unpack): 将容器中的数据值使⽤多个变量分别保存的过程
注意: 变量的个数和容器中数据的个数要保持⼀致
赋值运算符, 都是先执⾏等号右边的代码, 执⾏的结果,保存到等号左边的变量中
a = 10
b = 20
# 组包
c = b, a # 组包
print(type(c), c) # <class 'tuple'> (20, 10)
# 拆包
a, b = c
print(a, b)
x, y, z = [1, 2, 3]
print(x, y, z)
8. 匿名函数
匿名函数(Anonymous Function),也被称为 lambda 函数,是一种在代码中定义临时函数的方法,它不需要使用 def 关键字来定义函数
在 Python 中,可以使用 lambda 关键字来创建匿名函数。匿名函数通常用于简单的函数操作,其中函数体通常是由单个表达式组成,并且返回表达式的结果
语法:
lambda arguments: expression
lambda 是关键字,arguments 是函数的参数列表,expression 是函数体中的单个表达式,表达式的结果即为匿名函数的返回值
# 创建匿名函数
add = lambda x, y: x + y
# 使用匿名函数进行计算
result = add(3, 5) # 调用匿名函数,输出 8
- 在上述例子中,首先使用 lambda 创建了一个匿名函数
- 该函数接受两个参数 x 和 y,并返回它们的和
- 然后,我们通过调用该匿名函数,并传递参数 3 和 5,得到结果 8
练习题:请使用匿名函数编写一个程序,输入一个列表 numbers,并对列表中的每个元素进行平方运算,然后返回平方后的结果列表
示例输入:[1, 2, 3, 4, 5]
预期输出:[1, 4, 9, 16, 25]
# 匿名函数练习 - 平方列表元素
# 输入列表
numbers = [1, 2, 3, 4, 5]
# 使用匿名函数对列表元素进行平方运算
squared_numbers = list(map(lambda x: x ** 2, numbers))
# 输出平方后的结果列表
print(squared_numbers)
- 在上述代码中,我们使用 map() 函数结合匿名函数来对列表中的每个元素进行平方运算
- 匿名函数 lambda x: x ** 2 接受一个参数 x,并返回 x 的平方值
- 然后,我们使用 map(lambda x: x ** 2, numbers) 将匿名函数应用到 numbers 列表的每个元素上,得到一个迭代器对象
- 最后,将迭代器对象转换为列表,并赋值给变量 squared_numbers,即平方后的结果列表
- 最终,我们使用 print(squared_numbers) 输出平方后的结果列表
十八、面向对象
1. 理解面向对象
面向对象编程的核心概念是对象。对象是一个具体的实体,具有特定的属性和行为。属性是对象的状态或数据,而行为是对象能够执行的操作。通过将数据和操作封装在对象中,可以更加模块化地组织和设计程序
- 面向对象注重的是结果,谁(对象)能帮我完成这件事情
- 简而言之,就是找一个对象,让对象去做
2. 类和对象
⾯向对象的核⼼思想是 找⼀个对象去帮我们处理事情
在程序代码中 对象是由 类 创建的
类和对象,是 ⾯向对象编程思想中⾮常重要的两个概念
2.1 类
类定义了对象的属性和行为,并提供了可用于创建具体对象的方法
- 类名:是用于标识类的名称,通常采用大写字母开头的驼峰命名法
- 属性(属性):是类中存储数据的变量。每个对象都可以拥有自己的属性值。属性的访问、修改和赋值可以通过类的方法来实现
- 方法(Method):是类中定义的函数,用于操作和处理类的属性。方法可以访问和修改类的属性,并实现类的特定功能
- 构造函数(Constructor):是一种特殊的方法,当创建类的对象时自动调用。它用于初始化对象的属性,并可以接收参数来设置属性的初始值
- 实例化:是通过类创建对象的过程。在实例化过程中,类的构造函数被调用,分配内存空间,并返回一个可操作的对象实例
定义一个类
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def say_hello(self):
print("Hello, my name is", self.name)
def celebrate_birthday(self):
self.age += 1
# 创建类的实例
person1 = Person("Alice", 25)
person2 = Person("Bob", 30)
# 使用方法
person1.say_hello() # 输出:Hello, my name is Alice
person2.say_hello() # 输出:Hello, my name is Bob
# 使用属性
print(person1.age) # 输出:25
person2.celebrate_birthday()
print(person2.age) # 输出:31
2.2 对象
对象(Object)是面向对象编程中的一个基本概念,它是类的实例化结果。对象具有一组属性和方法,可以通过访问这些属性和方法来操作和处理对象的数据
- 属性(属性):对象的属性是存储在对象中的数据。每个对象可以具有自己的属性值,与其他对象相互独立。属性可以是各种数据类型,如整数、字符串、列表等
- 方法(Method):对象的行为是通过方法来实现的,方法是类中定义的函数。方法可以访问和修改对象的属性,并实现特定的功能。方法可以被其他对象调用,以达到对对象进行操作的目的
- 唯一性:每个对象都是唯一的,它具有与其他对象不同的标识。即使两个对象具有相同的属性值,它们也被视为不同的对象
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
print(self.name, "is barking!")
# 创建对象
dog1 = Dog("Buddy", 3)
dog2 = Dog("Max", 5)
# 访问属性
print(dog1.name) # 输出:Buddy
print(dog2.age) # 输出:5
# 调用方法
dog1.bark() # 输出:Buddy is barking!
dog2.bark() # 输出:Max is barking!
3. self的说明
在面向对象编程中,self 是一个特殊的参数,用于引用对象本身。它在方法内部使用,表示当前实例化的对象,并允许我们访问和修改对象的属性
在 Python 中,当调用对象的方法时,Python 会自动将该对象作为第一个参数传递给方法。通常,我们将第一个参数命名为 self,虽然你可以选择其他名称,但约定俗成的做法是使用 self
通过 self,我们可以在方法内部访问对象的属性和其他方法。它允许我们在对象的作用域内引用对象本身,以便对其进行操作。通过这种方式,我们可以在方法内获取对象的状态并执行特定的操作
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def say_hello(self):
print("Hello, my name is", self.name)
self.age += 1 # 访问并修改对象的属性
# 创建对象
person1 = Person("Alice", 25)
# 调用方法
person1.say_hello() # 输出:Hello, my name is Alice
# 访问属性
print(person1.age) # 输出:26
- 在上述示例中,构造函数 init 和方法 say_hello 中的 self 参数使我们能够引用对象本身
- 在 say_hello 方法中,我们使用 self.name 访问对象的 name 属性
- 并使用 self.age 访问和修改对象的 age 属性
4. 对象的属性操作
1、访问属性
可以使用
点操作符(.)
来访问对象的属性值。例如,object_name.attribute_name 可以获取对象的属性值
class Person:
def __init__(self, name):
self.name = name
person1 = Person("Alice")
print(person1.name) # 输出:Alice
2、修改属性
通过
点操作符(.)
结合赋值语句,可以修改对象的属性值。例如,object_name.attribute_name = new_value 可以将新值赋给对象的属性
class Person:
def __init__(self, name):
self.name = name
person1 = Person("Alice")
person1.name = "Bob" # 修改属性值
print(person1.name) # 输出:Bob
3、动态添加属性
可以通过
点操作符(.)
结合赋值语句,动态地向对象添加新的属性。例如,object_name.new_attribute = value 可以给对象添加新的属性,并为其赋值
class Person:
def __init__(self, name):
self.name = name
person1 = Person("Alice")
person1.age = 25 # 动态添加属性
print(person1.age) # 输出:25
4、删除属性
可以使用
del 关键字
删除对象的属性。例如,del object_name.attribute_name 可以从对象中删除指定的属性
class Person:
def __init__(self, name):
self.name = name
person1 = Person("Alice")
del person1.name # 删除属性
print(person1.name) # 抛出异常:AttributeError: 'Person' object has no attribute 'name'
5. 魔法方法
5.1 体验__init__()
这个__init__()
方法是一个特殊的魔法方法,用于在创建对象时进行初始化操作。它是在实例化对象后,自动调用的第一个方法
def __init__(self, param1, param2, ...):
# 初始化代码
- self 是一个约定俗成的参数名,表示对象本身
- param1, param2, … 是用于接收传递给构造函数的参数,可以根据实际需要定义参数列表
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# 创建对象并初始化
person1 = Person("Alice", 25)
print(person1.name) # 输出:Alice
print(person1.age) # 输出:25
在上述示例中,Person 类的 init() 方法接收 name 和 age 两个参数
并将它们分别赋值给 self.name 和 self.age 属性
当我们创建 person1 对象时,这些值会被传递给 init() 方法,最终初始化对象的属性
5.2 体验__str__()
__str__()方法是一个特殊的魔法方法,用于返回一个描述对象的字符串。它是在需要将对象转换为字符串表示时自动调用的方法
def __str__(self):
# 返回描述对象的字符串
- 在 str() 方法中,我们可以定义并返回一个描述对象的字符串,通常包含对象的相关信息,以便后续的打印、显示和调试等操作
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"Person(name={self.name}, age={self.age})"
# 创建对象
person1 = Person("Alice", 25)
# 调用 __str__() 方法并打印结果
print(person1) # 输出:Person(name=Alice, age=25)
5.3 体验__del__()
__del__() 方法是一个特殊的魔法方法,用于在对象被销毁时执行清理操作。它是在对象被垃圾回收机制回收前自动调用的方法
def __del__(self):
# 清理操作
- 在 del() 方法中,我们可以执行对象销毁前的清理操作,例如关闭文件、释放资源、解除引用等
- 需要注意的是,del() 方法的调用是由 Python 的垃圾回收机制决定的,而不是由我们手动调用。一般情况下,我们不需要显式地定义和使用 del() 方法,在大多数情况下,Python 会自动管理对象的销毁和垃圾回收
class MyClass:
def __init__(self, name):
self.name = name
def __del__(self):
print(f"Object {self.name} is being destroyed...")
# 执行其他清理操作
# 创建对象
obj1 = MyClass("Object 1")
obj2 = MyClass("Object 2")
# 删除对象引用
obj1 = None
obj2 = None
# 等待垃圾回收
import time
time.sleep(2)
- 在上述例子中,del() 方法被定义为在销毁对象时打印一条消息
- 当我们将 obj1 和 obj2 的引用设置为 None
- 即删除了对对象的引用时,它们将变成无法访问的,最终由垃圾回收机制回收
- 在这个过程中,del() 方法会被自动调用,打印消息并执行其他清理操作
5.4 综合案例
假设我们有一个简单的 Car 类代表汽车,它有以下属性:
make: 汽车制造商
model: 汽车型号
year: 汽车生产年份
我们希望在创建对象时使用 init() 方法初始化这些属性,方便地打印汽车的详细信息,以及在销毁对象时执行一些清理操作
class Car:
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
def __str__(self):
return f"Car make: {self.make}, model: {self.model}, year: {self.year}"
def __del__(self):
print(f"Car {self.make} {self.model} is being destroyed...")
# 可以执行其他清理操作,比如关闭文件或释放资源
# 创建对象
car1 = Car("Toyota", "Corolla", 2021)
car2 = Car("BMW", "X5", 2022)
# 打印对象信息
print(car1) # 输出:Car make: Toyota, model: Corolla, year: 2021
print(car2) # 输出:Car make: BMW, model: X5, year: 2022
# 删除对象引用
car1 = None
car2 = None
# 等待垃圾回收
import time
time.sleep(2)
-
在上述例子中,我们定义了 Car 类,并在 init() 方法中初始化汽车的属性
-
接着在 str() 方法中返回了描述汽车信息的字符串表示
-
最后,在 del() 方法中打印了销毁汽车对象的消息
-
我们创建了两个 Car 类的实例:car1 和 car2,并分别打印它们的信息
-
然后,我们将 car1 和 car2 的引用设置为 None,删除了对对象的引用
-
最后,通过等待垃圾回收,我们可以看到 del() 方法被调用,打印销毁汽车对象的消息
6. 封装
封装有以下几个主要目的:
- 数据隐藏:封装可以将类的属性隐藏起来,防止外部直接访问和修改类的内部数据。通过在类中定义私有属性(通常以双下划线开头)和公有方法来控制对属性的访问
- 实现数据保护:封装提供了一层保护屏障,可以对属性进行验证和过滤,确保只有合法的数据被存储在对象中
- 简化调用接口:封装通过将类的内部实现细节封装起来,提供了一个简化的调用接口,让用户使用对象时只需关注如何使用而无需了解具体实现
- 代码复用:封装可以使类的内部实现对外界隐藏,提供了模块化和代码复用的机制。其他代码可以通过调用类的公有方法来重用该类的功能,而无需了解内部的具体实现
class Car:
def __init__(self, make, model, year):
self.__make = make # 私有属性
self.__model = model # 私有属性
self.__year = year # 私有属性
def get_make(self):
return self.__make
def get_model(self):
return self.__model
def get_year(self):
return self.__year
def set_year(self, year):
if year > 1900:
self.__year = year
# 创建对象
car = Car("Toyota", "Corolla", 2021)
# 获取属性值
print(car.get_make()) # 输出:Toyota
print(car.get_model()) # 输出:Corolla
print(car.get_year()) # 输出:2021
# 修改属性值
car.set_year(2022)
print(car.get_year()) # 输出:2022
# 直接访问私有属性会报错
# print(car.__make) # 报错:'Car' object has no attribute '__make'
公有属性
公有属性是指在类的内部和外部都可以直接访问的属性。公有属性可以被类的方法、其他对象和外部代码直接访问和修改
class Car:
def __init__(self, make, model):
self.make = make # 公有属性
self.model = model # 公有属性
car = Car("Toyota", "Corolla")
print(car.make) # 输出:Toyota
print(car.model) # 输出:Corolla
car.make = "Honda"
print(car.make) # 输出:Honda
私有属性
私有属性是指只能在类的内部直接访问的属性,外部代码无法直接访问和修改私有属性
class Car:
def __init__(self, make, model):
self.__make = make # 私有属性
self.__model = model # 私有属性
car = Car("Toyota", "Corolla")
# 直接访问私有属性会报错
# print(car.__make) # 报错:'Car' object has no attribute '__make'
# 可以通过方法间接访问私有属性
def get_make(car):
return car.__make
print(get_make(car)) # 输出:Toyota
# 也可以通过特殊属性名访问私有属性
print(car._Car__make) # 输出:Toyota
7. 继承
继承是面向对象编程的一种重要概念,它允许一个类(称为子类或派生类)继承另一个类(称为父类、基类或超类)的属性和方法。子类可以重用父类的代码,并且可以增加或修改父类的行为
7.1 继承的作用:
- 代码重用:子类可以继承父类的属性和方法,避免了重复编写相似的代码,提高了代码的可重用性和可维护性
- 扩展性:子类可以在继承父类的基础上添加新的属性和方法,从而实现对父类行为的扩展或特化
- 统一性:继承可以帮助组织和管理相关的类,使代码更易于理解和组织
7.2 案例
class Animal:
def __init__(self, name):
self.name = name
def eat(self):
print(f"{self.name} is eating.")
class Dog(Animal):
def bark(self):
print("Woof!")
dog = Dog("Tommy")
dog.eat() # 输出:Tommy is eating.
dog.bark() # 输出:Woof!
在上述示例中,Animal 是父类,Dog 是子类 Dog 类继承了 Animal 类的属性和方法 子类可以使用 super()函数来调用父类的方法或属性
- 在这个例子中,Animal 类有一个名为 name 的属性和一个名为 eat() 的方法
- Dog 类继承了这些属性和方法,并添加了自己的方法 bark()
7.3 重写
重写(Override)是面向对象编程中的一种机制,它允许子类对父类的方法进行重新定义。通过重写,子类可以提供自己的实现逻辑,覆盖(或替代)父类的方法实现
class Animal:
def make_sound(self):
print("The animal makes a sound.")
class Dog(Animal):
def make_sound(self):
print("The dog says woof!")
animal = Animal()
animal.make_sound() # 输出:The animal makes a sound.
dog = Dog()
dog.make_sound() # 输出:The dog says woof!
在上述示例中,Animal 类有一个名为 make_sound() 的方法,它打印出动物发出的声音 Dog 类继承了 Animal 类,并重写了 make_sound() 方法,以提供狗特有的声音
7.4 super
子类重写父类方法后,父类的方法实现将会被完全覆盖。如果需要在子类方法中执行父类方法的逻辑,可以使用 super() 函数来调用父类方法
class Animal:
def make_sound(self):
print("The animal makes a sound.")
class Dog(Animal):
def make_sound(self):
super().make_sound()
print("The dog says woof!")
dog = Dog()
dog.make_sound()
8. 多态
- 是一种写代码,调用的一种技巧
- 同一个方法, 传入不同的对象, 执行得到不同的结果, 这种现象称为是多态
- 多态 可以 增加代码的灵活度
class Animal:
def make_sound(self):
pass
class Dog(Animal):
def make_sound(self):
print("The dog says woof!")
class Cat(Animal):
def make_sound(self):
print("The cat says meow!")
def animal_sounds(animals):
for animal in animals:
animal.make_sound()
dog = Dog()
cat = Cat()
animals = [dog, cat]
animal_sounds(animals)
- 在上述示例中,我们定义了一个基类 Animal,以及两个子类 Dog 和 Cat
- 它们都继承了 Animal 类,并重写了 make_sound() 方法
9. 属性和方法
实例对象
- 通过 类名() 创建的对象, 我们称为实例对象,简称实例
- 创建对象的过程称为是类的实例化
- 我们平时所说的对象就是指 实例对象(实例)
- 每个实例对象, 都有自己的内存空间, 在自己的内存空间中保存自己的属性(实例属性)
class Car:
def __init__(self, make, model):
self.make = make
self.model = model
def accelerate(self, speed):
print(f"The {self.make} {self.model} is accelerating to {speed} mph.")
car1 = Car("Toyota", "Corolla")
car2 = Car("Honda", "Civic")
print(car1.make, car1.model) # 输出:Toyota Corolla
print(car2.make, car2.model) # 输出:Honda Civic
car1.accelerate(60) # 输出:The Toyota Corolla is accelerating to 60 mph.
car2.accelerate(70) # 输出:The Honda Civic is accelerating to 70 mph.
在上述示例中,Car 类具有__init__()方法和 accelerate() 方法
通过调用 Car 类,我们创建了两个实例对象 car1 和 car2
每个实例对象都有自己独立的属性值
类对象
- 类对象 就是 类, 或者可以认为是 类名
- 类对象是 Python 解释器在执行代码的过程中 创建的
- 类对象的作用:
① 使用类对象创建实例 类名(),
② 类对象 也有自己的内存空间, 可以保存一些属性值信息(类属性)- 在一个代码中, 一个类 只有一份内存空间
class Car:
num_cars = 0 # 类级别的属性
def __init__(self, make, model):
self.make = make
self.model = model
Car.num_cars += 1 # 每次实例化对象时,数量加1
def display_info(self):
print(f"The {self.make} {self.model} is a car object.")
car1 = Car("Toyota", "Corolla")
car2 = Car("Honda", "Civic")
print(Car.num_cars) # 输出:2
car1.display_info() # 输出:The Toyota Corolla is a car object.
car2.display_info() # 输出:The Honda Civic is a car object.
在上述示例中,Car 类具有 num_cars 属性和 display_info() 方法
num_cars 是一个类级别的属性,用于记录类实例化的对象数量
display_info() 方法用于展示汽车对象的信息
10. 类方法和静态方法
10.1 类方法
在面向对象编程中,类方法(Class Method)是关联到类而不是实例的方法。类方法可以通过类对象调用,而无需创建实例对象
类方法使用 @classmethod 装饰器进行定义,第一个参数通常被命名为 cls,代表类本身。类方法可以访问类级别的属性和其他方法,并可以对其进行操作
class Car:
num_cars = 0 # 类级别的属性
def __init__(self, make, model):
self.make = make
self.model = model
Car.num_cars += 1 # 每次实例化对象时,数量加1
@classmethod
def display_num_cars(cls):
print(f"There are {cls.num_cars} cars.")
car1 = Car("Toyota", "Corolla")
car2 = Car("Honda", "Civic")
Car.display_num_cars() # 输出:There are 2 cars.
- 在上述示例中,Car 类具有 num_cars 属性和 display_num_cars() 类方法
- num_cars 是一个类级别的属性,用于记录类实例化的对象数量
- display_num_cars() 类方法用于展示汽车对象的数量
- 通过 @classmethod 装饰器,我们将 display_num_cars() 方法定义为类方法
- 类方法的第一个参数是类本身,通常被命名为 cls
- 在类方法内部,可以使用 cls 访问类级别的属性和方法
- 通过类对象 Car 调用 display_num_cars() 类方法
- 我们可以输出当前生成的汽车对象的数量
10.2 静态方法
静态方法使用 @staticmethod 装饰器进行定义。与普通的类方法不同,静态方法没有隐式参数,即不需要传递类或实例对象作为参数。它们在类的命名空间内定义,并通过类对象或类名进行调用
class MathUtils:
@staticmethod
def add(x, y):
return x + y
@staticmethod
def subtract(x, y):
return x - y
result1 = MathUtils.add(5, 3)
result2 = MathUtils.subtract(10, 7)
print(result1) # 输出:8
print(result2) # 输出:3
- 在上述示例中,MathUtils 类定义了两个静态方法 add() 和 subtract()
- 用于执行加法和减法运算
- 这些静态方法不需要引用实例对象或类的属性
- 通过类对象 MathUtils 直接调用静态方法,我们可以获得相应的计算结果
静态方法的特点:
1、不需要实例化对象,可以通过类对象或类名直接调用
2、不引用类的属性或方法,因此无法访问实例对象的属性
3、不会对类的状态产生影响,也不会修改类的属性
十九、文件操作
1. 文件介绍
计算机的 ⽂件,就是存储在某种 ⻓期储存设备 上的⼀段 数据
作⽤: 将数据⻓期保存下来,在需要的时候使⽤
1.计算机只认识 ⼆进制(0 1)
2.⽂件中存储的数据都是以⼆进制(0 1) 的形式去存储的
可以根据 ⽂件中的⼆进制内容,能否使⽤记事本软件 将其转换为⽂字
将⽂件分为两种: ⽂本⽂件和⼆进制⽂件
-
文本文件
1、能够使⽤记事本软件打开(能够使⽤记事本转换为⽂字)
2、txt, md, py , html, css, js , json -
二进制文件
1、不能使⽤记事本软件打开的
2、exe, mp3, mp4, jpg, png
2. 操作文件
2.1 打开文件
基本语法
file = open(file_path, mode)
- file_path 是要打开的文件的路径,可以是相对路径或绝对路径。如果文件不在当前工作目录下,需要提供完整的路径
- mode 是打开文件的模式,用于指定读取、写入、追加等方式
常见模式
模式 | 描述 |
---|---|
r | 只读模式(默认)。如果文件不存在,会引发 FileNotFoundError 异常 |
w | 写入模式。如果文件存在,则从头开始写入内容。如果文件不存在,则创建新文件并写入内容 |
a | 追加模式。如果文件存在,则在文件末尾追加内容。如果文件不存在,则创建新文件并写入内容 |
x | 创建模式。创建新文件并写入内容。如果文件已经存在,会引发 FileExistsError 异常 |
b | 二进制模式。用于处理二进制文件,如图像、视频等。在模式后面加上 “b”,例如 “rb” 或 “wb” |
t | 文本模式(默认)。用于处理文本文件,如普通的文本文件、CSV文件等。如果不指定 “b”,则为文本模式 |
open() 函数会返回一个文件对象,您可以使用该对象执行文件相关的操作,如读取内容、写入内容等。在操作完成后,应使用 file.close() 方法关闭文件,以释放相关资源
file = open("example.txt", "r") # 以只读方式打开文件
content = file.read() # 读取文件的全部内容
file.close() # 关闭文件
print(content)
2.2 写入文件
向⽂件中写⼊指定的内容.
前提: ⽂件的打开⽅式是 w 或者 a
file = open(file_path, mode)
file.write(content)
file.close()
- file_path 是要写入的文件的路径,可以是相对路径或绝对路径
- mode 是打开文件的模式,使用 “w” 或 “a” 分别表示写入模式和追加模式
- content 是要写入文件的内容,可以是一个字符串
在执行写入操作后,应使用 file.close() 方法关闭文件,以确保写入的内容被保存到文件中
file = open("example.txt", "w") # 使用写入模式打开文件
file.write("Hello, World!") # 写入内容到文件
file.close() # 关闭文件
- 在上述示例中,我们打开了名为 “example.txt” 的文件,并使用写入模式 “w”
- 然后,使用 write() 方法将字符串 “Hello, World!” 写入到文件中
- 最后,使用 close() 方法关闭文件
2.3 读文件
基本语法
file = open(file_path, mode)
content = file.read()
file.close()
- file_path 是要读取的文件的路径,可以是相对路径或绝对路径
- mode 是打开文件的模式,使用 “r” 表示只读模式
file = open("example.txt", "r") # 使用只读模式打开文件
content = file.read() # 读取文件的全部内容
file.close() # 关闭文件
print(content)
- 我们打开了名为 “example.txt” 的文件,并使用只读模式 “r”
- 然后,使用 read() 方法读取整个文件的内容,并将内容存储在变量 content 中
- 最后,使用 close() 方法关闭文件并打印文件内容
2.4 关闭文件
基本语法
file.close()
close() 方法没有参数,仅需在打开文件后的文件对象上调用即可
file = open("example.txt", "r") # 打开文件
content = file.read() # 读取文件内容
file.close() # 关闭文件
print(content)
- 我们使用 open() 函数打开文件,并使用只读模式 “r”
- 然后,使用 read() 方法读取文件内容,并将其存储在变量 content 中
- 最后,使用 close() 方法关闭文件
注意:
在使用 open() 打开文件进行读取或写入操作后,应在不再需要文件时调用 close() 方法。这样可以释放文件资源,并确保文件内容被正确保存
2.5 with open打开文件
使用 with open 结构可以更方便、更安全地处理文件的打开和关闭。它会自动在代码块结束后关闭文件,无需手动调用 close() 方法
with open(file_path, mode) as file:
# 文件操作,如读取、写入等
- file_path 是要打开的文件的路径,可以是相对路径或绝对路径
- mode 是打开文件的模式,用于指定读取、写入、追加等方式
在 with open 结构内部,您可以执行任何与文件相关的操作,如读取文件内容、写入内容等。代码块结束后,文件会自动关闭
with open("example.txt", "r") as file:
content = file.read()
print(content)
- 我们打开了名为 “example.txt” 的文件,并指定了只读模式 “r”
- 然后,在 with open 结构内部,使用 file.read() 方法读取文件的内容,并将其存储在变量 content 中
- 最后,我们打印文件的内容
2.6 按行读取文件内容
方法一:使用 for 循环迭代文件对象
with open("example.txt", "r") as file:
for line in file:
print(line)
- 我们使用 open() 函数以只读模式 “r” 打开文件
- 并使用 with 语句自动管理文件的打开和关闭
- 然后,我们使用 for 循环迭代文件对象 file,每次迭代都会读取文件的一行并将其赋值给变量 line
方法二:使用 readlines() 方法读取所有行
with open("example.txt", "r") as file:
lines = file.readlines()
for line in lines:
print(line)
- 我们使用 open() 函数打开文件
- 并使用 readlines() 方法一次性读取所有行,并将其存储在一个列表中
- 然后,我们使用 for 循环迭代列表中的每一行,并对其进行处理
3. json文件的处理
3.1 json文件的介绍
- json 基于⽂本,独⽴于语⾔的轻量级的数据交换格式
- 基于⽂本, 是⼀个⽂本⽂件, 不能包含图⽚,⾳视频等
- 独⽴于语⾔, 不是某个语⾔特有的, 每种编程语⾔都可以使⽤的
- 轻量级, 相同的数据, 和其他格式相⽐,占⽤的⼤⼩⽐较⼩
- 数据交换格式, 后端程序员 给前端的数据 (json, htmlxml)
3.2 json文件的语法
- 数据由键值对(key-value pairs)组成,键和值之间使用冒号(:)分隔
- 键必须是字符串,使用双引号(“”)括起来
- 值可以是字符串、数字、布尔值、对象、数组或null
- 多个键值对之间使用逗号(,)分隔
- JSON 对象使用花括号({})包裹,键值对位于花括号内部
- JSON 数组使用方括号([])包裹,值位于方括号内部
3.3 json文件的书写
{
"name": "John",
"age": 30,
"isStudent": false,
"hobbies": ["reading", "cooking", "sports"],
"address": {
"street": "123 Main St",
"city": "New York",
"country": "USA"
},
"friends": [
{
"name": "Alice",
"age": 28
},
{
"name": "Bob",
"age": 32
}
]
}
3.4 json文件的读取
- 导包 import json
- 读打开⽂件
- 读⽂件
json.load(⽂件对象)
返回的是 字典(⽂件中是对象)或者列表(⽂件中是数组)
import json
# 打开 JSON 文件
with open('example.json') as json_file:
# 加载 JSON 数据
data = json.load(json_file)
# 访问 JSON 数据中的键值对
name = data['name']
age = data['age']
# 输出结果
print(f"Name: {name}")
print(f"Age: {age}")
- 上述代码首先使用 open 函数打开 JSON 文件
- 并通过 json.load 函数将文件内容加载为 JSON 数据
- 然后,你可以通过键名称来访问数据中的值
- 最后,通过打印输出的方式展示读取到的数据
练习
假设我们有一个名为 data.json 的 JSON 文件
{
"students": [
{
"name": "John",
"age": 20,
"grade": "A"
},
{
"name": "Alice",
"age": 22,
"grade": "B"
},
{
"name": "Bob",
"age": 21,
"grade": "A"
}
]
}
输出一下结果
读取 data.json 文件
统计学生的个数,并输出结果
计算所有学生的平均年龄,并输出结果
找出成绩为 “A” 的学生,并输出他们的姓名和年龄
import json
# 读取 JSON 文件
with open('data.json') as json_file:
data = json.load(json_file)
# 统计学生个数
students = data['students']
num_students = len(students)
print(f"学生个数:{num_students}")
# 计算平均年龄
total_age = sum(student['age'] for student in students)
average_age = total_age / num_students
print(f"平均年龄:{average_age}")
# 找出成绩为 "A" 的学生
a_students = [student for student in students if student['grade'] == 'A']
print("成绩为 A 的学生:")
for student in a_students:
print(f"姓名:{student['name']},年龄:{student['age']}")
结果
学生个数:3
平均年龄:21.0
成绩为 A 的学生:
姓名:John,年龄:20
姓名:Bob,年龄:21
解析
1、首先,我们读取了 JSON 文件,使用 json.load 函数将文件内容加载为 JSON 数据,并存储在变量 data 中
2、接着,我们通过访问 data 中的键值对来进行分析。首先,我们统计了学生的个数,通过读取 data[‘students’] 获取学生列表,并使用 len 函数获取列表的长度,即学生个数
3、然后,我们计算了所有学生的平均年龄。我们使用列表推导式来遍历学生列表,取出每个学生的年龄,并将年龄求和。然后,将总年龄除以学生个数,得到平均年龄
4、最后,我们找出了成绩为 “A” 的学生。同样使用列表推导式来遍历学生列表,筛选出成绩为 “A” 的学生。然后,通过迭代输出了他们的姓名和年龄
3.5 json的写入
⽂件对象.write(字符串) 不能直接将 Python 的列表 和字典
作为参数传递
想要将 Python 中的数据类型存为 json ⽂件, 需要使⽤ json
提供的⽅法, 不再使⽤ write
步骤:
- 导包 import json
- 写(w) ⽅式打开⽂件
- 写⼊
json.dump(Python 中的数据类型, ⽂件对象)
import json
# 要写入的数据
data = {
"name": "John",
"age": 30,
"isStudent": False
}
# 写入 JSON 文件
with open('output.json', 'w') as json_file:
json.dump(data, json_file)
- 使用 open 函数打开一个名为 output.json 的文件,并指定写入模式为 ‘w’
- 然后,我们使用 json.dump 函数将 data 写入到文件中
请确保将 ‘output.json’ 替换为你希望写入的实际 JSON 文件的路径。这里假设你想要将数据写入与代码相同的目录下,如果不是,请相应调整文件路径
二十、异常
1. 介绍异常
程序在运⾏时,如果 Python 解释器 遇到到⼀个错误,会停⽌程序的执⾏,并且提示⼀些错误信息,这就是异常
程序停⽌执⾏并且提示错误信息 这个动作, 抛出异常(raise 关键字)
捕获异常: 程序遇到异常, 默认动作是终⽌代码程序的执⾏, 遇
⻅异常之后, 可以使⽤ 异常捕获, 让程序代码继续运⾏,不会终
⽌运⾏
2. 基本语法
try:
# 尝试执行可能会引发异常的代码块
# ...
except ExceptionType1:
# 如果捕获到 ExceptionType1 异常,则执行这里的代码来处理异常情况
# ...
except ExceptionType2:
# 如果捕获到 ExceptionType2 异常,则执行这里的代码来处理异常情况
# ...
else:
# 如果没有捕获到任何异常,则执行这里的代码
# ...
finally:
# 不管是否捕获到异常,最终都会执行这里的代码
# ...
3. 异常类型
类型 | 描述 |
---|---|
ZeroDivisionError | 除以零引发的异常 |
TypeError | 类型错误,例如使用不兼容的类型进行操作 |
ValueError | 值错误,例如传递了非法的参数值 |
FileNotFoundError | 文件未找到引发的异常 |
IndexError | 索引超出范围引发的异常等 |
4. 练习
def divide_numbers(a, b):
try:
result = a / b
return result
except ZeroDivisionError:
return "除数不能为零"
except TypeError:
return "请输入两个数字作为参数"
# 测试
print(divide_numbers(10, 0)) # 除数为零
print(divide_numbers(10, "2")) # 参数类型错误
print(divide_numbers(10, 2)) # 正常计算
-
在这个例子中,divide_numbers 函数用于将两个数相除并返回结果。在函数体内,我们使用 try-except 语句来捕获可能引发的异常
-
在 try 块中,我们尝试执行除法运算,将结果保存在 result 变量中,并返回它
-
如果除数为零,那么会引发 ZeroDivisionError 异常,在 except ZeroDivisionError 块内捕获该异常,并返回相应的错误信息
-
如果参数类型不正确,例如传递了一个字符串作为除数,那么会引发 TypeError 异常,在 except TypeError 块内捕获该异常,并返回相应的错误信息
5.模块
5.1导入模块
方式一
import 模块名
# 使⽤模块中的内容
模块名.⼯具名
# 举例
import random
import json
random.randint(a, b)
json.load()
json.dump()
方式二
from 模块名 import ⼯具名
# 使⽤
⼯具名 # 如果是函数和类需要加括号
# 举例
from random import randint
from json import load, dump
randint(a, b)
load()
dump()
5.2 模块的查找顺序
- 在导⼊模块的时候 会先在当前⽬录中找模块, 如果找到,就直接使⽤
- 如果没有找到回去系统的⽬录中进⾏查找, 找到,直接使⽤没有找到, 报错
__name __
的作用
- 每个代码⽂件都是⼀个模块
- 在导⼊模块的时候, 会执⾏模块中的代码(三种⽅法都会)
- name 变量
3.1 name 变量 是 python 解释器⾃动维护的变量
3.2 name 变量,如果代码是直接运⾏, 值是 “main”
3.3 name 变量, 如果代码是被导⼊执⾏, 值是 模块名(即代码⽂件名)
两种情况下 __name __
的值会发生变化:
第一种情况
如果一个模块是直接被运行的(作为主程序),那么 __name __ 的值将被设置为字符串 “main”。这意味着你可以使用 if name == “main”: 来判断当前模块是否正在被直接执行
假设你有一个名为 my_module.py 的模块,其中包含一些函数。当你直接运行这个模块时,其中的 name 变量将会是 “main”
# my_module.py
def my_function():
print("Hello, world!")
if __name__ == "__main__":
my_function()
当你运行此模块时,my_function() 函数将被调用打印出 “Hello, world!”
第二种情况
如果一个模块被其他模块导入,那么 __name __ 的值将是模块的名称(不包含路径和扩展名)
假设你有另一个名为 main.py 的模块,想要导入 my_module.py 中的 my_function() 函数
# main.py
import my_module
my_module.my_function()
上面的代码中,my_module 被导入,并且 my_module.my_function() 被调用。此时,my_module.py 中的 name 的值将是 “my_module”
6. 包
在 Python 中, 包 是⼀个⽬录, 只不过在这个⽬录存在⼀个⽂
件 init.py(可以是空的)
将功能相近或者相似的代码放在⼀起的
在 Python 中使⽤的时候,不需要可以是区分是包还是模块, 使
⽤⽅式是⼀样的
random 模块 (单个代码⽂件)
json 包(⽬录)
from 包名 import *
模块名.目标