新手快速掌握python基础与高级语法 ———— 一篇就够

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的版本

python各版本路径

  • Python2.X
  • Python3.X

二、pycharm编译器

1. 了解pycharm编译器

PyCharm 是一种专业的 Python 集成开发环境(IDE),它由 JetBrains 公司开发并提供。PyCharm 提供了一系列功能和工具,旨在帮助开发者提高 Python 开发效率和质量

2. 编译器的作用

  1. 代码编辑和调试:PyCharm 提供了强大的代码编辑器,支持代码自动完成、语法检查、代码重构等功能,同时还具备强大的调试功能,可帮助开发者快速排查代码问题

  2. 项目管理:PyCharm 支持创建和管理多个 Python 项目,可以方便地进行项目配置、依赖管理、模块导入等操作,提高项目组织和管理的效率

  3. 版本控制:PyCharm 集成了常用的版本控制系统,如 Git、SVN 等,可以直接在 IDE 中进行代码版本管理、冲突解决等操作,方便团队协作开发

  4. 智能代码分析:PyCharm 内置了智能代码分析功能,可以检测和纠正代码错误、提供代码提示和建议,帮助开发者编写高质量的 Python 代码

  5. 测试和自动化:PyCharm 支持单元测试和集成测试,可以方便地运行和管理测试用例,同时还提供了自动化测试等功能,帮助开发者确保代码质量和可靠性

  6. 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. 输入的特点

  1. 代码从上到下执行,如果遇到input函数之后,会暂停执行,等待用户输入完成,如果不输入会一直等待
  2. 输入过程中,如果遇到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中,循环分为whilefor两种,最终实现效果相同

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. 文档注释

⽂档注释的本质,还是注释, 只不过书写的位置和作⽤⽐较特殊

  1. 书写位置, 在函数名的下⽅使⽤ 三对双引号进⾏的注释
  2. 作⽤: 告诉别⼈这个函数如何使⽤的, ⼲什么的
  3. 查看, 在调⽤的时候, 将光标放到函数名上,使⽤快捷键

Ctrl q(Windows)
Mac(ctrl j)
ctrl(cmd) B 转到函数声明中查看(按住Ctrl(cmd) ⿏标左键点击)

4. 函数的嵌套使用

在⼀个函数定义中调⽤另⼀个函数

  1. 函数定义不会执⾏函数体中的代码
  2. 函数调⽤会执⾏函数体中的代码
  3. 函数体中代码执⾏结束会回到函数被调⽤的地⽅继续向下执⾏
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. 多态

  1. 是一种写代码,调用的一种技巧
  2. 同一个方法, 传入不同的对象, 执行得到不同的结果, 这种现象称为是多态
  3. 多态 可以 增加代码的灵活度
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. 属性和方法

实例对象

  1. 通过 类名() 创建的对象, 我们称为实例对象,简称实例
  2. 创建对象的过程称为是类的实例化
  3. 我们平时所说的对象就是指 实例对象(实例)
  4. 每个实例对象, 都有自己的内存空间, 在自己的内存空间中保存自己的属性(实例属性)
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
每个实例对象都有自己独立的属性值

类对象

  1. 类对象 就是 类, 或者可以认为是 类名
  2. 类对象是 Python 解释器在执行代码的过程中 创建的
  3. 类对象的作用:
    ① 使用类对象创建实例 类名(),
    ② 类对象 也有自己的内存空间, 可以保存一些属性值信息(类属性)
  4. 在一个代码中, 一个类 只有一份内存空间
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文件的读取

  1. 导包 import json
  2. 读打开⽂件
  3. 读⽂件
    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

步骤:

  1. 导包 import json
  2. 写(w) ⽅式打开⽂件
  3. 写⼊
    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 __的作用

  1. 每个代码⽂件都是⼀个模块
  2. 在导⼊模块的时候, 会执⾏模块中的代码(三种⽅法都会)
  3. 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 *
模块名.目标
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值