语言概述与特点

动态语言特性与解释型语言的优劣

动态语言(如Python、JavaScript)和解释型语言(如Python、Ruby)是两个相关但不同的概念:动态语言强调类型检查在运行时进行,变量类型可动态变更;解释型语言强调无需预先编译为机器码,由解释器逐行执行。两者常重叠(如Python既是动态语言也是解释型语言),其优劣势可分别总结如下:

  1. 动态语言特性的核心特点:变量无强制类型声明,类型检查在运行时进行,支持动态修改对象结构(如添加属性/方法)。

  2. 动态语言特性的优势:

  • 开发效率高:无需写类型声明,代码更简洁,适合快速迭代和原型开发(如Python一行代码实现复杂功能)。

  • 灵活性强:可动态调整变量类型和对象结构,适配多变的业务需求(如JavaScript中对象可随时添加属性)。

  • 学习门槛低:语法更接近自然语言,初学者易上手。

  1. 动态语言特性的劣势:

  • 运行时错误风险高:类型错误(如字符串与数字相加)只能在运行时发现,可能导致线上故障。

  • 性能损耗:运行时类型检查增加额外计算开销,执行效率通常低于静态类型语言(如Java、C#)。

  • 重构难度大:大型项目中,类型不明确可能导致修改一处代码引发连锁错误,维护成本高。

  1. 解释型语言的核心特点:源代码直接由解释器逐行解析执行,无需编译为机器码(或仅进行部分即时编译)。

  2. 解释型语言的优势:

  • 跨平台性好:依赖解释器而非底层机器码,一次编写可在多平台运行(如Python代码在Windows/Linux上无需修改)。

  • 开发周期短:修改代码后无需重新编译,可立即运行,适合快速测试和调试。

  • 部署简单:直接部署源代码,无需处理编译后的二进制文件,降低环境配置复杂度。

6. 解释型语言的劣势:

  • 执行速度较慢:逐行解释比编译型语言(如C、Go)的预编译机器码执行效率低(尤其计算密集型任务)。

  • 依赖解释器:运行环境必须安装对应解释器,增加部署依赖。

  • 代码保密性差:源代码直接暴露,不如编译型语言的二进制文件难以逆向。

  1. 总结: 动态语言和解释型语言的优势集中在开发效率、灵活性和跨平台性,适合快速开发、脚本任务、Web应用等场景;劣势则体现在运行效率、错误检查和大型项目维护,因此在高性能、高可靠性要求的场景(如操作系统、实时系统)中,静态编译型语言(如C、Rust)仍占主导。

跨平台能力与丰富的标准库

  • 跨平台:Python代码能在Windows、Linux、macOS等系统上直接运行,解释器会处理不同系统的差异,实现"一次编写,到处运行"。

  • 标准库丰富:自带大量模块,涵盖文件操作、网络通信、数据处理等功能,无需额外安装就能完成多数任务,即"电池已包含"理念。

应用领域(Web开发、数据分析、人工智能等)

  1. 数据分析与科学计算:借助Pandas、NumPy等库处理数据,Matplotlib、Seaborn可视化数据,是科研和商业分析的常用工具。

  2. 人工智能与机器学习:TensorFlow、PyTorch等主流框架基于Python,广泛用于图像识别、自然语言处理等AI任务。

  3. Web开发:Django、Flask等框架简化网站搭建,豆瓣、Instagram等均采用Python开发。

  4. 自动化运维与脚本:用于编写批量处理脚本、自动化测试、服务器管理等,提高运维效率。

  5. 爬虫开发:通过Requests、Scrapy等库抓取网页数据,应用于信息聚合、数据分析等场景。

  6. 教育领域:语法简单易懂,是初学者入门编程的首选语言,也常用于高校计算机课程。

  7. 游戏开发:可用于游戏脚本编写(如《文明IV》)、游戏测试等环节。

  8. 嵌入式系统与物联网:在树莓派等平台上,用于控制硬件、开发物联网应用。

以上只是Python的一部分功能,请记住“Python无所不能”,剩下的功能请在后续的学习探索中慢慢发掘吧

开发环境搭建

Python解释器安装

安装Python解释器的步骤简单直观,以下是主流系统的安装方法:

Windows系统:

  • 访问官网:https://www.python.org/downloads/,点击"Download Python X.X.X"(X为最新版本)

  • 运行安装包,勾选"Add Python to PATH"(关键,自动配置环境变量)

  • 点击"Install Now",等待完成即可

macOS系统:

  • 方法1:官网下载对应版本的.pkg安装包,双击安装

  • 方法2:通过Homebrew(包管理工具)安装,终端输入:brew install python3

Linux系统:

  • 多数Linux(如Ubuntu)预装Python,终端输入python3可查看版本

  • 如需安装/更新,终端输入:sudo apt install python3(Debian/Ubuntu)或sudo yum install python3(CentOS)

验证安装:

安装完成后,打开终端(Windows用命令提示符或PowerShell),输入python(Windows)或python3(macOS/Linux),出现Python版本信息即成功。

如需退出解释器,输入exit()或按Ctrl+Z(Windows)/Ctrl+D(macOS/Linux)。

常用IDE推荐(PyCharm、VS Code)

请自行搜寻下载教程

第一个Python程序:Hello World

print('helloworld')

基础语法结构

变量命名规范与动态类型

  1. 变量命名规范:

  • 变量名必须以字母或下划线开头,不能以数字开头。

  • 只能包含字母、数字和下划线。

  • 避免使用编程语言的关键字。

  • 使用描述性名称:变量名应反映其用途。

  1. 动态类型 :

动态类型是指在程序运行时才确定变量类型的特性。与静态类型不同,动态类型允许变量在运行时改变类型。其核心特点有:

  • 变量无需声明类型:直接赋值即可

  • 类型可以动态改变:同一个变量可以存储不同类型的数据。

  • 运行时类型检查:错误(如类型不匹配)通常在运行时被发现。

 #动态类型示例

variable = 10  # 初始为整数类型

print(type(variable))  # 输出: <class 'int'>

variable = "hello"  # 运行时改变为字符串类型

print(type(variable))  # 输出: <class 'str'>

#尝试操作可能引发运行时错误

try:

    result = variable + 5  # 字符串和整数相加,会报错

except TypeError as e:

    print(f"错误: {e}")  # 输出: 错误: can only concatenate str (not "int") to str

 

基本数据类型(int, float, str, bool)

1.查询数据类型:type(数据名)
2.数据类型:
2.1数值类型
2.1.1整数类型:

引导符号

输出

十进制

num=987

987

二进制

0b或0B

num=ob1010101

85

八进制

0o或0O

num=0o765

501

十六进制

0x或0X

num=0x87ABF

555711

2.1.2浮点数类型:

浮点型运算:有一定概率运算后增加一些不确定的尾数,可以利用round函数保留所需要的位数。

print(0.1+0.2)                #输出结果是0.30000000000000004

print(round(0.1+0.2,1))       #输出结果是0.3

print(round(0.52+0.1314,3))   #输出结果为0.651

print(round(0.52+0.1314,1))   #输出结果为0.7

print(round(0.7))             #输出结果为1 

round函数在处理以5结尾的数字时采用的是银行家算法,即当一个数字恰好以5结尾时,会将其舍入到最接近的偶数。如,print(round(2.5)),其输出结果为2

2.1.3复数类型:

复数是由实数部分和虚数部分组成的数,通常表示为 a + bi 的形式

x=123+456j

print('实数部分为:',x.real)

print('虚数部分为:',x.image)

2.2字符串类型
2.2.1转义字符:

转义字符

作用

\n

换行

\t

横向跳到下一个制表位

\"

"

\'

'

\\

\

转义字符前加R或r

将转义字符无效化

2.2.2字符串的索引与切片:
s='helloworld'

print(s[0],s[-10],s[4])  #输出结果为h h o

print(s[2:7],s[-8:-3])  #输出结果为llowo llowo

print(s[:5],s[5:])  #输出结果为hello world

2.2.3操作符:

操作符

作用

x+y

连接字符串x和字符串y

x*n或n*x

复制n次字符串x

x in s

判断字符串x是否为字符串s的子串(True or False)

2.2.4算数运算符:

运算符

描述

+

-

*

/

//

取整除

%

取余

**

指数

2.3布尔类型

布尔类型是用来表示真值或者假值的数据类型。在Python中用True和False表示,其中True表示整数1,False表示整数0。

3.数据类相间的转换

函数作用:

int(x)

将x转换为整数类型

float(x)

将x转换为浮点数类型

str(x)

将x转换为字符串类型

chr(x)

将x转换为一个字符

ord(x)

将一个字符x转换为其对应的整数值

hex(x)

将一个字符x转换为一个十六进制字符串

oct(x)

将一个字符x转换为一个八进制字符串

bin(x)

将一个字符x转换为一个二进制字符串

流程控制语句

条件语句(if-elif-else结构与三元表达式以及模式匹配)

1. if-elif-else结构

num=eval(input('请输入密码:'))
if num==5201314:
print('密码正确,你好先生')
elif num==5211314:
print('密码正确,你好女士')
else: 
print('密码错误')

2. 三元表达式

在Python中,三元表达式可以被看作是if-else语句的简化版本。

num=eval(input('请输入密码:'))
print('密码正确,你好先生')if num==5201314 else(print('密码正确,你好女士')if num==5211314 else print('密码错误'))

从代码复杂度上来看三元表达式显然更简洁。然而,这并不意味着任何情况下都应该使用三元表达式。如果条件或者返回值的计算逻辑很复杂,那么使用if-else语句可能会更好,因为它的结构更清晰,更易于理解。

3. 模式匹配

score=input('请输入成绩等级:')
match score:
	case 'A':
			print('优秀')
	case 'B':
			print('及格')
	case 'C':
			print('不及格')
	case _ :
			pass

循环结构(for与while循环的使用场景)

1. for循环

s=0
for i in range(1,11):  #range函数:产生一个[n,m)的整数序列
	s+=i
print('1到10的累加和为:',s)

2. for...else...语句

for循环的变种,当for循环正常循环结束后,执行else语句。

numbers = [4, 6, 8, 9, 10]
target = 7
for num in numbers:
    if num == target:
        print(f"找到了目标数字 {target}")
        break
else:  # 循环正常结束(未被 break)时执行
    print(f"列表中没有找到目标数字 {target}")

3. while循环

s=0
i=1  #初始化变量
while i<=100: #条件判断
	s+=i #语句块
	i+=i #改变变量
print('1到100的累加值为:',s)

4. while...else..语句

while循环的变种,当while循环正常循环结束后,执行else语句。

attempts = 0

while attempts < 3:

    user_input = input("请输入一个数字(如 123):")

    if user_input.isdigit(): #str.isdigit()所有字符都是数字

        print(f"有效数字:{user_input}")

        break

    else:

        print("输入无效,请重试。")

        attempts += 1

else:  # 循环正常结束(未 break)时执行

    print("连续3次输入无效,程序退出。")

循环控制关键字(break, continue, pass)

1. break: 直接结束程序运行。

2. continue: 跳过本次循环的后续代码,并继续执行下一次循环操作。

3. pass: 只起到占位符的作用,使语法结构完整、不报错。

4. 示例:斐波那契数列实现

斐波那契数列是一个经典的数学序列,其中每个数字都是前两个数字的和,通常以 0 和 1 开始。

  • 方法一:

def fibonacci_recursive(n):
    if n <= 0:
        return []
    elif n == 1:
        return [0]
    elif n == 2:
        return [0, 1]
    else:
        seq = fibonacci_recursive(n-1)
        seq.append(seq[-1] + seq[-2])
        return seq
# 示例:生成前10个斐波那契数

print(fibonacci_recursive(10))  # 输出: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
  • 方法二:

def fibonacci_iterative(n):
    if n <= 0:
        return []
    elif n == 1:
        return [0]
    seq = [0, 1]
    while len(seq) < n:
        seq.append(seq[-1] + seq[-2])
    return seq
# 示例:生成前10个斐波那契数
print(fibonacci_iterative(10))  # 输出: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
  • 方法有很多,可参考AI或其他文章进行思路开拓。

核心数据结构

列表(list)

1. 定义: 列表是指一系列的按特定顺序排列的元素组成。列表是Python中内置的可变序列,列表中的元素可以是任意数据类型。

2. 列表的创建方式:

  • 直接创建:列表名=[元素1,元素2,...,元素n]

  • 使用内置函数list()创建:列表名=list(序列)

3. 列表的删除: del 列表名

4. enumerate(枚举)函数与列表:

  for index,item in enumerate(lst) #输出index和item

5. 列表中的遍历操作

#for循环
for i in lst:
	print(i)
#根据索引进行遍历
for i in range(0,len(lst)):
	print(i,lst[i])
#用enumerate函数进行遍历
for index,item in enumerate(lst):
print(index,item)

6. 列表的操作方法

操作符/函数

作用

lst.append(x)

在列表lst最后增加一个元素

lst.insert(inder,x)

在列表中第index位置增加一个元素

lst.clear()

清除列表lst中的所有元素

lst.pop(index)

将列表lst中第index元素删除

lst.remove(x)

将列表lst中出现的第一个元素删除

lst.reverse(x)

将列表lst中的元素反转

lst.copy()

拷贝列表中的所有元素生成一个新的列表

7. 列表排序

#使用sort方法在原列表上进行更改
#lst.sort(key=None,reverse=False)
#key代表排序规则,reverse代表排序方式,False代表升序
lst=['banana','apple','Cat','Orange']
lst.sort()
print(lst) #输出:['Cat','Orange','apple','banana']
lst.sort(reverse=True)
print(lst) #输出:['banana','apple','Orange','Cat']
lst.sort(key=str.lower) #字符转为小写后比较
print(lst)  #输出:['apple','banana','Cat','Orange']
#使用内置函数sorted()生成一个新列表
#sorted(iterable,key=None,revers=False)
#iterable表示排序的对象
new__lst=sorted(lst)
new__lst=sorted(lst,reverse=True)
new__lst=sorted(lst,key=str.lower)
#输出与sort方法的输出相同

8. 列表生成式

#lst=[expression for item in range()]
#lst=[expression for item in range() if condition]
#expression是列表中数据的获取方法,item是元素个数,condition是判断条件
import random
lst=[item for item in range(1,11)]
print(lst) #输出:[1,2,3,4,5,6,7,8,9,10]
lst=[item*item for item in range(1,11)]
print(lst) #输出:[1,4,9,16,25,36,49,64,81,100]
lst=[random.randint(1,100) for _ in range(1,11)] #randint:生成随机整数
print(lst) #输出:[50,25,31,62,46,54,88,84,86,91]
lst=[i for i in range(10) if i%2==0]
print(lst) #输出:[0,2,4,6,8]

9. 二维列表

#读取二维列表
for row in lst:
	for item in row:
		pass
#生成二维列表
lst=[[j for j in range(5)] for i in range(4)] #j代表几列,i代表几行
for j in lst: #这个二维列表有几行
	for i in j: #这个二维列表每行有几列
		print(i,end='\t')
	print()

元组(tuple)的特性与使用场景

1. 定义: 元组是Python中内置的不可变序列,用()定义元组,元素与元素间使用英文逗号进行分隔,只有一个元素时逗号也不能省略。

2. 元组的创建方式

- 用()直接创建:元组名=(元素1,元素2,...,元素n)

- 使用内置函数tuple()创建:元组名=tuple(序列)

3. 元组的删除: del 元组名

4. 元组中的索引操作:

#查找
t=(1,2,3,4,5)
print(t[0])  #输出:1
#切片
t2=t[0:5:2] #从元组t的第0位开始取,取到第4位,中间间隔为2
print(t2) #输出(1,3,5)

5. 元组的遍历:

#for循环
for item in t:
	print(item)
#根据索引进行遍历
for i in range(len(t)):
	print(i,t[i])
#使用enumerate函数枚举遍历
for index,item in enumerate(t):
	print(index,item)

6. 元组的生成式

元组名=(i for i in range(a,b))
元组名=tuple(序列)
元组名=(i for i in range(a,b) if 条件)

7. 依次读取__next__

t=(1,2,3)
print(t.__next__()) #输出:1
print(t.__next__()) #输出:2
print(t.__next__()) #输出:3
print(t) #输出:()

8. 元组与列表的区别

元组

列表

不可变序列

可变序列

无法实现添加、删除、修改元素等操作

可用append()、pop()等方法实现添加、删除、修改元素等操作

支持切片访问元素,不支持修改操作

支持切片访问和修改列表中的元素

访问和处理速度快

访问和处理速度慢

可以作为字典的键

不能作为字典的键

字典(dict)的键值对管理与高效查找

1. 定义: 字典类型是根据一个信息去查找另一个信息的方式构成了“键值对”,他表示了索引作用的键和对应的值构成的成对关系。

2. 字典的创建方式

  • 使用{}直接创建:d={key1:value1,key2:value2,.....}

  • 通过映射函数创建字典,使用内置函数dict()创建:

v=zip(lst1,lst2)

d=dict(v)
  • 使用参数创造:d=dict(key1:value1,key2:value2,....)

3. 字典的删除: del 字典名

4. 字典元素的取值: d[key]或d.get(key)

5. 字典元素的遍历:

#遍历出key与value的元组

for element in d.items():

	pass

#分别遍历出key和value

for key,value in d.items():

	pass

6. 字典的操作方法:

操作方法

描述说明

d.key

获取所有的key数据

d.value

获取所有的value数据

d.pop(key,default)

key存在时获取对应的value,同时删除这对值,否则获取默认值

d.popitem

随机从字典中取出一个key-value对,结果为元组类型,同时将该key-value从字典中删除

d.clear

清空字典中所有的key-value对

d[key]=value

添加

7. 字典生成式

d={key:value for item in range()}

d={key:value for key,value in zip(lst1,lst2)}

集合(set)的去重与集合运算

1. 定义: Python中集合与数学中的集合概念一致,是一个无序的不重复元素序列,集合中只能存储不可变数据类型,在Python中用{}定义。与列表、字典一样,都是Python中的可变数据类型。

2. 集合的创建方式:

  • 使用{}直接创建:s={element1,element2,.....,element N}

  • 使用内置函数set()创建:s=set(可迭代对象)

3. 集合的删除: del 集合名

4. 集合的操作符:

操作符

作用

A&B

集合A与集合B的交集

A|B

集合A与集合B的并集

A-B

集合A与集合B的差集A-A&B

A^B

集合A与集合B的补集A+B-A&B

5. 集合的操作方法:

操作方法

作用

s.add(x)

如果x不在集合中,则将x添加到集合s

s.remove(x)

如果x在集合中,则将其删除,反之则报错

s.clear(x)

清除集合中所有元素

6. 集合的遍历:

#for循环
for item in s:
	pass
#使用enumerate函数
for index,item in enumerate(s)
	print(index,item)

7. 集合的生成式:

s={i for i in range(a,b)}
s={i for i in range(a,b) if 条件}

列表、元组、字典、集合的区别

数据类型

序列类型

元素可否重复

是否有序

定义符号

列表list

可变序列

可重复

有序

[ ]

元组tuple

不可变序列

可重复

有序

( )

字典dict

可变序列

key不可重复,value可重复

无序

{key:value}

集合set

可变序列

不可重复

无序

{ }

函数与模块化编程

函数定义与参数传递(位置参数、关键字参数)

1. 函数的定义: 函数是将一段实现功能的完整代码使用函数名称进行封装,通过函数名称进行调用,以此达到一次编写、多次调用的目的。

2. 自定义函数:

def 函数名称(参数列表):

	函数体

	[return返回值列表]

3. 函数调用: 函数名称(参数列表)

4. 参数:

  • 位置参数:是指调用时的参数个数和顺序必须与定义的参数个数相同。

  • 关键字参数:是在函数调用时,使用‘形参名称=值’的方式进行传参,传递参数顺序可以与定义时参数的顺序不同。

  • 默认值参数:是在函数定义时,直接对形式参数进行赋值,在调用时如果该参数不传值,将使用默认值,如果改参数传值,则使用传递的值。

  • 可变参数:

  • 个数可变的位置参数:在参数前加一颗星(*参数名),函数调用时可接收任意个数的实际参数,并放到一个元组中。

  • 个数可变的关键字参数:在参数前加两颗星(**参数名),函数调用时可接收任意个‘参数=值‘形式的参数,并放到一个字典中。

返回值与多返回值的元组解包

1. 返回值return: 如果函数的运行结果需要在其它函数中使用,那么这个函数就应该被定义成带返回值的函数。函数的运行结果使用return关键字进行返回, return可以出现在函数的任意一个位置用于结束函数。返回值可以是一个值或多个值,如果返回值是多个,结果是一个元组类型。

2. 元组解包的基本用法

name, age, city = get_user_info()
print(name)  # 输出:Alice
print(age)   # 输出:30
print(city)  # 输出:Beijing
#变量数量与元组元素数量必须一致

3. 元组解包的进阶用法:处理数量不匹配的情况

#使用星号(*)表达式捕获多个元素
# 示例:获取前1个元素,剩余元素用列表接收
user_info = ("Alice", 30, "Beijing", "female", "programmer")
name, *others = user_info
print(name)    # 输出:Alice
print(others)  # 输出:[30, 'Beijing', 'female', 'programmer']
# 示例:获取中间元素,前后用列表接收
before, city, after = user_info
print(before)  # 输出:['Alice', 30]
print(city)    # 输出:Beijing
print(after)   # 输出:female, programmer(注意:如果after不加'*'这里after只接收最后1个元素)
#用_忽略不需要的元素
user_info = ("Alice", 30, "Beijing")
name, , city = userinfo  # 忽略age
print(name)  # 输出:Alice
print(city)  # 输出:Beijing
#结合*和_忽略多个元素
user_info = ("Alice", 30, "Beijing", "female", "programmer")
name, *_, job = user_info  # 忽略中间的30、Beijing、female
print(name)  # 输出:Alice
print(job)   # 输出:programmer

lambda表达式的适用场景

1. lambda 表达式(匿名函数) 是 Python 中一种简洁的函数定义方式,其语法为lambda 参数: 表达式。适用于需要简单函数且仅使用一次的场景。

2. 常见场景:作为 “一次性” 函数参数

#对复杂结构(如字典、元组)排序时,用 lambda 指定排序键:
students = [("Alice", 20), ("Bob", 18), ("Charlie", 22)]
# 按年龄排序(第二个元素)
sorted_by_age = sorted(students, key=lambda x: x[1])
print(sorted_by_age)  # 输出:[('Bob', 18), ('Alice', 20), ('Charlie', 22)]
#筛选可迭代对象中符合条件的元素:
numbers = [1, 2, 3, 4, 5, 6]
# 筛选偶数
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers)  # 输出:[2, 4, 6]
#对可迭代对象中的元素做转换:
numbers = [1, 2, 3, 4]
# 计算每个数的平方
squared = list(map(lambda x: x **2, numbers))
print(squared)  # 输出:[1, 4, 9, 16]

3. 常见场景: 简化函数返回值

#当函数需要返回另一个简单函数时,lambda 可以替代def定义的嵌套函数,使代码更紧凑。
def make_adder(n):
    # 返回一个“加n”的函数
    return lambda x: x + n
add5 = make_adder(5)
print(add5(3))  # 输出:8(3+5)
print(add5(10)) # 输出:15(10+5)

4. 常见场景: 作为字典 / 列表中的 “简单逻辑” 元素

# 用字典存储不同的计算逻辑
operations = {
    "add": lambda a, b: a + b,
    "subtract": lambda a, b: a - b,
    "multiply": lambda a, b: a * b
}
print(operations["add"](2, 3))      # 输出:5
print(operations["subtract"](5, 2)) # 输出:3
# 在字典或列表中需要嵌入简单的操作逻辑时,lambda 可以避免单独定义函数,使代码更集中。

模块导入机制(import与from...import区别)

1. import 语句:

  • import 模块名 [as 别名],导入整个模块,使得模块中的所有公开成员(函数、类、变量等)可以通过「模块名。成员名」的方式访问。

  • 导入的是整个模块,不会污染当前作用域(成员需通过模块名访问)

  • 适合需要使用模块中多个成员的场景 - 可以通过 as 关键字指定别名,简化代码书写

import math  # 导入 math 模块
print(math.pi)  # 通过模块名访问成员
print(math.sqrt(16))  # 调用模块中的函数
# 使用别名简化访问
import math as m
print(m.pi)  # 等价于 math.pi

2. from…import语句:

  • from 模块名 import 成员名 [as 别名] 或 from 模块名 import *,直接导入模块中的指定成员(或所有成员),可以直接通过「成员名」访问,无需前缀模块名。

  • 直接导入成员,使用时无需模块名前缀,代码更简洁

  • 可能导致命名冲突(如果当前作用域已有同名变量 / 函数)

  • from...import * 会导入模块中所有公开成员(以下划线 _ 开头的私有成员除外),但可读性差,不建议在生产代码中使用

# 导入指定成员
from math import pi, sqrt
print(pi)  # 直接使用成员名
print(sqrt(16))
# 为成员指定别名
from math import pi as圆周率
print(圆周率)
# 导入所有成员(不推荐)
from math import *
print(cos(0))  # 可以直接使用 math 中的所有公开成员

3. import与from...import核心区别总结

维度

import 模块

from 模块 import 成员

访问方式

必须通过 模块名.成员名

直接使用 成员名

作用域污染

不会污染(成员在模块命名空间)

可能污染(成员直接进入当前作用域)

适用场景

使用模块中多个成员

仅使用模块中少数几个成员

命名冲突风险

低(需通过模块名区分)

高(可能与当前作用域成员重名)

文件操作与异常处理

文件读写模式(r/w/a与二进制模式)

1. 打开函数open(): 打开一个已存在的文件或传建一个新文件。open(name,mode,encoding)

2. 文本模式:

- 文本模式用于处理文本文件(如 .txt、.py 等),读写内容为字符串(str 类型),会自动处理换行符(跨平台转换)。

模式

含义

特点

r

只读模式(默认)

文件必须已存在,否则报错;指针位于文件开头

w

只写模式

若文件不存在则创建;若已存在则清空原有内容;指针位于文件开头

a

追加模式

若文件不存在则创建;写入内容追加到文件末尾;指针位于文件末尾

r+

读写模式

文件必须已存在;可读写,指针从开头开始

w+

读写模式

清空文件后读写(类似 w 但可读)

a+

读写模式

追加内容,且可读取(但读操作需手动移动指针)

# 1. 读取文件(r模式)

with open("test.txt", "r", encoding="utf-8") as f:

    content = f.read()  # 读取全部内容(字符串)

    print(content)

# 2. 写入文件(w模式)

with open("test.txt", "w", encoding="utf-8") as f:

    f.write("Hello, World!")  # 覆盖原有内容

# 3. 追加内容(a模式)

with open("test.txt", "a", encoding="utf-8") as f:

    f.write("\nAppend this line.")  # 新增内容到末尾
  • 文本模式操作的相关方法:

  • read()方法: 文件对像.read(num),多次调用时,下一次会在上一次结束处读取。num为从文件中读取数据的长度(单位:字节),如果没有num则读取所有。

  • readlines()方法: 按照行的方式把整个文件中的内容进行一次性读取,并返回为一个列表,其中每一行的数据为一个元素。列表名=文件对象.readlines()

  • for循环读取文件行: for line in open('python.txt','r'):print(line)

  • flush()方法: 文件对象.flush(),将内容刷新,把内容真正写入文件,close也有相同效果

3. 二进制模式:

- 二进制模式用于处理非文本文件(如图片、音频、视频、压缩包等),读写内容为字节流(bytes 类型),不处理换行符,需显式指定 b 标志。

模式

含义

对应文本模式

rb

二进制只读模式(默认)

r

wb

二进制只写模式

w

ab

二进制追加模式

a

rb+/wb+/ab+

二进制读写模式

r+/w+/a+

# 1. 读取图片(二进制文件)

with open("image.png", "rb") as f:

    data = f.read()  # 读取字节流(bytes类型)

# 2. 复制图片(二进制读写)

with open("image.png", "rb") as src, open("copy.png", "wb") as dst:

    dst.write(src.read())  # 直接写入字节流

4. 文本模式与二进制模式的区别:

维度

文本模式

二进制模式

操作对象

字符串(str)

字节流(bytes)

编码要求

需要指定 encoding(如 utf-8)

不需要指定编码(直接操作原始字节)

适用文件

文本文件(.txt、.py 等)

非文本文件(图片、音频、视频等)

换行处理

自动转换(如 \n 与 \r\n)

不处理,原样读写

5. close()方法: 将内容刷新并关闭文件对象

with上下文管理器的资源自动释放

1. with语句能自动处理资源的分配与释放,避免因忘记关闭资源而导致的内存泄漏或文件损坏等问题。当处理文件、网络连接、数据库连接等有限资源时,with 语句的核心优势是无论代码块正常执行还是发生异常,都会确保资源被正确释放。

# 风险:若中间代码报错,可能导致文件未关闭

f = open("test.txt", "r")

content = f.read()

f.close()  # 必须手动调用,否则资源可能泄露

# 安全:无论是否发生异常,文件都会自动关闭

with open("test.txt", "r") as f:

    content = f.read()

# 离开 with 代码块后,f 已自动关闭,无需手动操作

2. with 语句的实现依赖于 上下文管理器协议,即对象必须实现两个特殊方法:

  • enter():进入 with 代码块时调用,返回需要管理的资源(如文件对象)。

  • exit():离开 with 代码块时调用(无论正常退出还是异常退出),负责释放资源。

class MyFile:
    def init(self, filename, mode):
        self.filename = filename
        self.mode = mode
        
    def enter(self):
        self.file = open(self.filename, self.mode)
        return self.file  # 返回资源给 as 后的变量

    
    def exit(self, exc_type, exc_val, exc_tb):
        self.file.close()  # 自动释放资源
        # 处理异常(可选)
        if exc_type:
            print(f"发生异常:{exc_val}")
        return False  # 不抑制异常,让其继续传播
# 使用自定义上下文管理器
with MyFile("test.txt", "w") as f:
    f.write("Hello, Context Manager!")

3. with语句的使用场景:

  • 文件操作

with open("data.csv", "r", encoding="utf-8") as f:

    for line in f:

        print(line.strip())
  • 数据库连接

import sqlite3

with sqlite3.connect("mydb.db") as conn:

    cursor = conn.cursor()

    cursor.execute("SELECT * FROM users")

# 离开代码块后,连接自动关闭
  • 网络连接

import socket

with socket.socket() as s:

    s.connect(("example.com", 80))

    s.send(b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")

# 套接字自动关闭
  • 锁机制

import threading

lock = threading.Lock()

with lock:

    # 临界区代码(自动获取和释放锁)

    pass

常见异常类型(IOError, ValueError等)

1. 基础异常类

  • Exception:所有非系统退出类异常的基类,几乎所有自定义异常都继承自它。

  • BaseException:所有异常的顶层基类,包括 Exception 和系统退出类异常(如 SystemExit)。

2. 常见具体异常类型

异常类型

触发场景

示例

IOError

输入/输出操作失败(如文件未找到、权限不足)

尝试打开不存在的文件 open("nonexist.txt")

FileNotFoundError

尝试打开不存在的文件(Python 3 新增,IOError 的子类)

open("missing.txt", "r")

ValueError

传入的值类型正确但不符合要求

int("abc")(字符串无法转换为整数)

TypeError

操作或函数应用于不适当类型的对象

"2" + 2(字符串与整数拼接)

IndexError

序列索引超出范围

[1,2,3][5](列表索引越界)

KeyError

字典中查找不存在的键

{"a":1}["b"](访问不存在的字典键)

NameError

引用未定义的变量

print(undefined_var)(变量未声明)

ZeroDivisionError

除数为零

10 / 0(数学上的除以零错误)

AttributeError

尝试访问对象不存在的属性

"string".nonexist_attr(字符串无此属性)

SyntaxError

代码语法错误(编译时异常)

if True: print("hi") 缺少缩进

IndentationError

缩进错误(Python 特有的语法错误)

代码块缩进不一致

ImportError

导入模块失败

import nonexist_module(模块不存在)

KeyboardInterrupt

用户按下 Ctrl+C 中断程序

运行时强制终止程序

3. 异常处理示例

使用 try...except 捕获并处理异常:

try:
    # 可能触发异常的代码
    num = int(input("请输入数字:"))
    result = 10 / num
    print(f"结果:{result}")

except ValueError:
    print("错误:输入不是有效的数字")

except ZeroDivisionError:
    print("错误:除数不能为零")

except Exception as e:
    # 捕获其他未预料的异常
    print(f"发生未知错误:{e}")

4. 注意

  • 异常类型反映了错误的具体原因,针对性捕获能让代码更健壮。

  • 避免使用 except Exception 捕获所有异常(可能掩盖真正的问题),应优先捕获具体异常。

  • 调试时,异常的堆栈信息(traceback)会显示错误类型和位置,是排查问题的关键。

try-except-finally的完整处理流程

1. 基本结构

try:
    # 可能发生异常的代码块(核心逻辑)
    risky_operation()

except 异常类型1 [as 变量名]:
    # 若发生「异常类型1」,执行此处代码(处理异常)
    handle_error_type1()

except (异常类型2, 异常类型3) [as 变量名]:
    # 若发生「异常类型2」或「异常类型3」,执行此处代码
    handle_error_type2_or_3()

else:
    # 若 try 块无异常,执行此处代码(可选)
    no_error_operation()

finally:
    # 无论是否发生异常,都会执行此处代码(释放资源等)
    must_execute_operation()

2. 执行流程详解

1. try 块优先执行:

程序首先执行 try 中的代码,这是可能发生异常的核心逻辑。

2. 若 try`块发生异常:

  • 立即中断 try块执行,跳转到对应的 except块匹配异常类型。

  • 若找到匹配的 except 块,执行其中的异常处理代码。

  • 若未找到匹配的 except 块,异常会向上传播(可能导致程序终止)。

  • 无论是否匹配到 except,最终都会执行 finally 块。

3. 若 try 块无异常:

  • 执行完 try 块后,跳过所有 except 块。

  • 若有 else 块,执行 else 中的代码(else 是无异常时的附加逻辑)。

  • 最后执行 finally 块。

4. finally 块的必然性:

无论 try 块是否异常、except 块是否匹配、甚至 return/break 语句,finally 块一定会执行,常用于释放资源(如关闭文件、断开连接)。

3. 实例演示

def read_file_safely(filename):
    file = None  # 初始化变量,避免未定义错误

    try:
        file = open(filename, "r", encoding="utf-8")
        content = file.read()
        print("文件内容:", content[:100])  # 打印前100字符
        return "读取成功"  # 无异常时返回

    except FileNotFoundError:
        print(f"错误:文件 '{filename}' 不存在")
        return "读取失败"  # 异常时返回

    except UnicodeDecodeError as e:
        print(f"错误:文件编码异常 - {e}")
        return "读取失败"
    else:
        print("额外操作:文件读取无异常,记录日志")  # 仅无异常时执行

    finally:
        # 无论是否异常,确保文件关闭
        if file:
            file.close()
            print("资源释放:文件已关闭")

# 测试:文件存在且正常
read_file_safely("test.txt")

# 测试:文件不存在
read_file_safely("nonexist.txt")

4. 关键特性

  • except 多分支:可按异常类型精准处理,避免一刀切捕获所有异常。

  • else 块作用:分离「核心逻辑」和「无异常时的附加逻辑」,使代码更清晰。

  • finally不可替代:即使在 try 或 except 中使用 return,finally仍会执行(如下):

def demo():

      try:

          return 1  # 尝试返回

      finally:

          print("finally 执行了")  # 仍会执行

  demo()  # 输出:finally 执行了,返回值 1

5. 使用场景

  • try:包裹可能出错的核心代码(如文件操作、网络请求)。

  • except:针对性处理可预见的异常(如文件不存在、网络超时)。

  • else:处理无异常时的附加逻辑(如日志记录、结果校验)。

  • finally:必做的收尾工作(如关闭文件/连接、释放锁、清理临时文件)。

面向对象编程基础

类与对象的概念解析

1. 类(Class): 类是对一类事物共同特征和行为的抽象描述,它不特指某个具体的事物,而是定义了这类事物"是什么"(属性)和"能做什么"(方法)。

  • 属性(Attribute):类中定义的变量,用于描述事物的特征。例如"人"类的属性可以是姓名、年龄、性别等。

  • 方法(Method):类中定义的函数,用于描述事物的行为。例如"人"类的方法可以是走路、说话、吃饭等。

2. 对象(Object): 对象是类的具体实例,是根据类创建的具体个体。它具有类中定义的属性和方法,并且属性有具体的值。一个类可以创建多个对象,每个对象的属性值可以不同,但都遵循类定义的结构。

3. 面向对象的核心意义

  • 封装性: 类将属性和方法封装在一起,对外隐藏实现细节,只暴露必要的接口。

  • 复用性: 通过类可以快速创建多个对象,避免重复代码。

  • 扩展性: 基于已有类可以创建新类(继承),实现功能的扩展。

4. 代码示例(Python)

# 定义一个"人"类(模板)
class Person:
    # 属性(特征)
    def init(self, name, age):
        self.name = name  # 姓名
        self.age = age    # 年龄

    

    # 方法(行为)
    def speak(self):
        print(f"我叫{self.name},今年{self.age}岁")

# 创建对象(具体实例)
person1 = Person("张三", 20)  # 第一个对象
person2 = Person("李四", 30)  # 第二个对象

# 调用对象的方法
person1.speak()  # 输出:我叫张三,今年20岁
person2.speak()  # 输出:我叫李四,今年30岁

#在这个例子中,`Person`是类,`person1`和`person2`是根据该类创建的两个不同对象,它们都有`name`、`age`属性和`speak()`方法,但属性值不同。

构造方法(init)与实例属性

1. 构造方法(\__init__): 构造方法是类中一个特殊的方法,用于在创建对象时初始化对象的属性。

  • 特点:

  • 当通过类创建对象时,\__init__ 会被自动调用。

  • 第一个参数必须是self,代表当前正在创建的对象本身。

  • 可以定义额外参数,用于为对象的属性赋值。

  • 作用:

  • 为新创建的对象设置初始状态(属性值)。

  • 执行对象创建时必需的初始化操作(如打开文件、连接数据库等)。

2. 实例属性: 实例属性是属于具体对象的属性,每个对象的实例属性可以有不同的值。它们通常在构造方法中通过 self.属性名 定义。

  • 特点:

  • 每个对象的实例属性独立存储,修改一个对象的属性不会影响其他对象。

  • 必须通过对象(或 self)访问,如 p.name 或 self.name。

3. 构造方法与实例属性的关系: 构造方法是定义和初始化实例属性的主要场所。通过 __init__ 方法的参数,可以在创建对象时为实例属性赋值,使每个对象一创建就具备具体的属性值。

class Person:

    # 构造方法:初始化实例属性
    def init(self, name, age):  # name和age是外部传入的参数
        self.name = name  # 定义并初始化实例属性name
        self.age = age    # 定义并初始化实例属性age

    def introduce(self):
        # 通过self访问实例属性
        print(f"我叫{self.name},今年{self.age}岁")

# 创建对象时,自动调用__init__,传入参数初始化属性
p1 = Person("张三", 20)
p2 = Person("李四", 30)

# 访问实例属性
print(p1.name)  # 输出:张三
print(p2.age)   # 输出:30

# 调用方法(方法内部使用了实例属性)
p1.introduce()  # 输出:我叫张三,今年20岁

4. 关键点说明

  • self 的作用:self 是构造方法(及所有实例方法)的第一个参数,代表当前对象。通过 self.属性名 定义的属性,会成为该对象的实例属性。

  • 默认参数:构造方法可以使用默认参数,使创建对象时某些属性可选:

  class Person:
      def init(self, name, age=18):  # age默认值为18
          self.name = name
          self.age = age
  p = Person("王五")  # 不传入age,使用默认值18
  print(p.age)  # 输出:18
  • 实例属性的动态添加:除了在 __init__ 中定义,也可以在对象创建后动态添加实例属性(但不推荐,会导致代码混乱):

 p1 = Person("张三", 20)

  p1.gender = "男"  # 动态添加gender属性

继承与方法重写(super()函数使用)

1. 继承(Inheritance): 继承是指 一个类(子类)可以继承另一个类(父类)的属性和方法,并可以在此基础上添加新的属性或方法,或修改父类的方法。

  • 作用:

  • 代码复用:无需重复编写父类已有的代码。

  • 功能扩展:在父类基础上添加新功能。

  • 多态实现:为不同子类的同名方法提供统一调用接口。

# 父类(基类)
class Parent:
    def parent_method(self):
        print("这是父类的方法")

# 子类(派生类),继承自Parent
class Child(Parent):
    def child_method(self):
        print("这是子类的方法")

# 子类对象可以调用父类和自身的方法
c = Child()
c.parent_method()  # 输出:这是父类的方法(继承自父类)
c.child_method()   # 输出:这是子类的方法(自身方法)

2. 方法重写(Override): 子类的"个性化改造"

当子类需要对父类的方法进行**修改或扩展**时,可以定义与父类同名的方法,这称为方法重写。

  • 场景:

  • 父类方法的逻辑不满足子类需求。

  • 需要在父类方法基础上添加新逻辑。

class Animal:
    def speak(self):
        print("动物发出声音")

# 子类Dog重写speak方法
class Dog(Animal):
    def speak(self):  # 与父类方法同名
        print("汪汪汪")

# 子类Cat重写speak方法
class Cat(Animal):
    def speak(self):  # 与父类方法同名
        print("喵喵喵")

dog = Dog()
dog.speak()  # 输出:汪汪汪(调用重写后的方法)
cat = Cat()
cat.speak()  # 输出:喵喵喵(调用重写后的方法)

3. super()函数: super() 用于在子类中**调用父类的方法或属性**,尤其在方法重写时,可以保留父类的逻辑并添加子类特有的逻辑。

  • 常见用法:

1. 在子类构造方法中调用父类构造方法

确保父类的属性被正确初始化。

2. 在重写的方法中调用父类的同名方法

复用父类逻辑,再添加子类特有的逻辑。

#在构造方法中使用super()
class Person:
    def init(self, name, age):
        self.name = name
        self.age = age

class Student(Person):
    def init(self, name, age, school):
        # 调用父类的__init__方法,初始化name和age
        super().__init__(name, age)
        # 子类新增属性
        self.school = school
    def introduce(self):
        print(f"我叫{self.name},{self.age}岁,在{self.school}上学")

s = Student("张三", 18, "北京大学")
s.introduce()  # 输出:我叫张三,18岁,在北京大学上学

 

#在重写方法中使用super()

class Animal:
    def move(self):
        print("动物在移动")

class Bird(Animal):
    def move(self):
        # 先调用父类的move方法
        super().move()
        # 再添加子类特有的逻辑
        print("鸟在飞翔")

bird = Bird()
bird.move()

# 输出:
# 动物在移动
# 鸟在飞翔

4. 关键点说明

  • super()的本质:super() 并非直接调用"父类",而是调用**继承链中的下一个类**(适用于多继承场景)。

  • 参数传递:在super()调用中,无需手动传递self参数,Python会自动处理。

  • 多继承中的super(): 在多继承(如class C(A, B))中,super() 会按照**MRO(方法解析顺序)** 调用下一个类的方法,避免方法调用冲突。

魔术方法(如__str__, len)的实用案例

1. __str__():自定义对象的字符串表示

__str__() 用于定义对象被print()或str()转换时的字符串格式,让对象的输出更具可读性。

#定义一个Book类,打印时显示书籍的基本信息
class Book:
    def init(self, title, author, pages):
        self.title = title
        self.author = author
        self.pages = pages

    # 自定义字符串表示
    def str(self):
        return f"《{self.title}》- 作者:{self.author}({self.pages}页)"
book = Book("Python编程", "张三", 300)
print(book)  # 自动调用__str__(),输出:《Python编程》- 作者:张三(300页)
print(str(book))  # 同样调用__str__(),输出同上

2. __len__():让对象支持len()函数

__len__() 用于定义当调用len(obj)时的返回值,通常用于表示对象的"长度"或"数量"。

#定义一个ShoppingCart类,用len()获取购物车中商品数量
class ShoppingCart:
    def init(self):
        self.items = []  # 存储商品的列表

    def add_item(self, item):
        self.items.append(item)

    # 定义len()的返回值为商品数量
    def len(self):
        return len(self.items)

cart = ShoppingCart()
cart.add_item("苹果")
cart.add_item("香蕉")
print(len(cart))  # 自动调用__len__(),输出:2

3. __getitem__()和__setitem__():让对象支持索引操作

这两个方法用于使对象可以像列表或字典一样通过[ ]进行取值和赋值。

#定义一个StudentList类,支持用索引访问学生
class StudentList:
    def init(self):
        self.students = []

    # 支持obj[index]取值
    def getitem(self, index):
        return self.students[index]

    # 支持obj[index] = value赋值
    def setitem(self, index, value):
        self.students[index] = value

students = StudentList()
students.students = ["张三", "李四", "王五"]
print(students[0])  # 调用__getitem__(),输出:张三
students[1] = "赵六"  # 调用__setitem__()
print(students[1])  # 输出:赵六

4. __add__():自定义对象的加法运算

__add__() 用于定义两个对象相加(+)时的逻辑。

#定义一个Vector类,实现向量的加法
class Vector:
    def init(self, x, y):
        self.x = x
        self.y = y

    # 自定义加法:两个向量的x和y分别相加
    def add(self, other):
        return Vector(self.x + other.x, self.y + other.y)

    def str(self):
        return f"Vector({self.x}, {self.y})"

v1 = Vector(2, 3)
v2 = Vector(4, 5)
v3 = v1 + v2  # 自动调用__add__()
print(v3)  # 输出:Vector(6, 8)

5. __bool__():自定义对象的布尔值判断

__bool__() 用于定义对象在布尔判断(如 if obj:)时的返回值,默认情况下所有对象都为True。

#定义一个Account类,余额为0时视为False
class Account:
    def init(self, balance=0):
        self.balance = balance

    # 余额为0时返回False,否则返回True
    def bool(self):
        return self.balance > 0

acc1 = Account(100)
acc2 = Account(0)

if acc1:
    print("账户1有余额")  # 会执行

if acc2:
    print("账户2有余额")  # 不会执行

6. 魔术方法的核心价值

  • 增强可读性:如__str__()让对象的输出更直观。

  • 模拟内置类型:通过__len__()、__getitem__()等让自定义类像列表、字典一样使用。

  • 简化逻辑:将特定操作(如加法、判断)封装在魔术方法中,使代码更简洁。

标准库常用模块

os和sys模块的系统交互

1. os模块: 主要用于与操作系统进行交互,提供了访问文件系统、环境变量、进程管理等功能,它更偏向于操作系统层面的操作。

#os模块常用功能
import os

# 获取当前工作目录
current_dir = os.getcwd()
print(f"当前工作目录: {current_dir}")

# 列出目录中的文件和文件夹
files = os.listdir(current_dir)
print(f"目录内容: {files}")

# 创建目录
new_dir = "test_dir"
os.mkdir(new_dir)

# 重命名文件/目录
os.rename(new_dir, "new_test_dir")

# 删除目录
os.rmdir("new_test_dir")

# 获取环境变量
path_var = os.environ.get("PATH")
print(f"PATH环境变量: {path_var}")

# 执行系统命令
os.system("echo Hello from system command!")

3. sys模块: 主要用于与Python解释器本身进行交互,提供了与解释器相关的配置和操作,比如命令行参数、解释器版本信息、标准输入输出等。

#sys模块常用功能
import sys

# 获取命令行参数
print(f"命令行参数: {sys.argv}")

# 获取Python解释器版本信息
print(f"Python版本: {sys.version}")

# 获取系统平台
print(f"系统平台: {sys.platform}")

# 标准输出重定向
print("这是标准输出")
sys.stdout.write("这也是标准输出\n")

# 退出程序
sys.exit(0)  # 0表示正常退出,非0表示异常退出

# 获取模块搜索路径
print(f"模块搜索路径: {sys.path}")

datetime模块的时间处理

1. datetime 模块: datetime 模块是处理日期和时间的核心工具,提供了简洁且功能丰富的类来操作时间,包括日期计算、格式转换、时区处理等。

2. datetime的核心类:

  • date: 处理年、月、日(日期)

  • time: 处理时、分、秒、微秒(时间)

  • datetime: 同时处理日期和时间(最常用)

  • timedelta: 表示时间间隔(用于日期加减)

  • tzinfo/timezone: 处理时区(Python 3.2+ 新增 timezone 简化时区操作)

3. 常用功能示例:

#获取当前时间
from datetime import datetime, date, time

# 获取当前日期时间(datetime对象)
now = datetime.now()
print("当前时间:", now)  # 输出:2023-10-15 14:30:45.123456

# 获取当前日期(date对象)
today = date.today()
print("当前日期:", today)  # 输出:2023-10-15

# 单独获取年、月、日、时、分、秒
print("年:", now.year)     # 2023
print("月:", now.month)    # 10
print("日:", now.day)      # 15
print("时:", now.hour)     # 14
print("分:", now.minute)   # 30
print("秒:", now.second)   # 45

#创建指定时间
from datetime import datetime, date, time

# 创建指定日期时间(datetime)
dt = datetime(2023, 10, 1, 8, 30, 0)
print("指定时间:", dt)  # 2023-10-01 08:30:00

# 创建指定日期(date)
d = date(2023, 12, 25)
print("指定日期:", d)  # 2023-12-25

# 创建指定时间(time)
t = time(18, 45, 30)
print("指定时间:", t)  # 18:45:30

#时间格式转换(字符串与datetime互转)
#strftime():将 datetime 转为字符串(格式化输出)
#strptime():将字符串转为 datetime(解析输入)
from datetime import datetime

# datetime -> 字符串(格式化)
now = datetime.now()
str1 = now.strftime("%Y-%m-%d %H:%M:%S")  # 年-月-日 时:分:秒
str2 = now.strftime("%Y年%m月%d日 %H时%M分")  # 中文格式
print("格式化后:", str1)  # 2023-10-15 14:30:45
print("中文格式:", str2)  # 2023年10月15日 14时30分

# 字符串 -> datetime(解析)
str_time = "2023-10-01 08:30:00"
dt = datetime.strptime(str_time, "%Y-%m-%d %H:%M:%S")
print("解析后的时间:", dt)  # 2023-10-01 08:30:00

"""

常用格式化符号
%Y:四位数年份(如 2023)
%m:两位数月份(01-12)
%d:两位数日期(01-31)
%H:24小时制小时(00-23)
%M:分钟(00-59)
%S:秒(00-59)

"""

# 时间间隔计算(timedelta)
#timedelta 用于表示时间差,可直接与 datetime 进行加减运算。
from datetime import datetime, timedelta
now = datetime.now()
# 计算3天后的时间
future = now + timedelta(days=3)
print("3天后:", future)  # 2023-10-18 14:30:45.123456
# 计算1小时30分钟前的时间
past = now - timedelta(hours=1, minutes=30)
print("1小时30分钟前:", past)  # 2023-10-15 13:00:45.123456
# 计算两个时间的差
delta = future - past
print("时间差(天):", delta.days)          # 3
print("时间差(总秒数):", delta.total_seconds())  # 270000.0(3天×86400秒)
#时区处理
#使用 pytz 库(需安装:pip install pytz)或 Python 3.9+ 的 zoneinfo 处理时区。
from datetime import datetime
import pytz  # 第三方时区库
# 获取纽约时间(UTC-4/UTC-5,随季节变化)
ny_tz = pytz.timezone('America/New_York')
ny_time = datetime.now(ny_tz)
print("纽约时间:", ny_time.strftime("%Y-%m-%d %H:%M:%S"))
# 获取北京时区(UTC+8)
bj_tz = pytz.timezone('Asia/Shanghai')
bj_time = datetime.now(bj_tz)
print("北京时间:", bj_time.strftime("%Y-%m-%d %H:%M:%S"))

json模块的数据序列化

1. json模块: 提供了对 JSON 数据格式的序列化(将 Python 对象转换为 JSON 字符串)和反序列化(将 JSON 字符串转换为 Python 对象)功能,是处理 JSON 数据的核心工具。

2. json模块中的核心函数

  • json.dumps():将 Python 对象序列化为 JSON 字符串

  • json.dump():将 Python 对象序列化为 JSON 字符串并写入文件

  • json.loads():将 JSON 字符串反序列化为 Python 对象

  • json.load():从文件中读取 JSON 字符串并反序列化为 Python 对象

3. Python 与 JSON 类型对应关系: 序列化时,Python 类型会被转换为对应的 JSON 类型

Python 类型

JSON 类型

dict

object

list, tuple

array

str

string

int, float

number

True

true

False

false

None

null

4. 序列化(Python → JSON)

import json
# 定义一个 Python 字典(可序列化的对象)

data = {
    "name": "Alice",
    "age": 30,
    "is_student": False,
    "hobbies": ["reading", "hiking"],
    "address": {
        "city": "New York",
        "zipcode": "10001"
    },
    "score": None
}

# 使用 dumps() 转为 JSON 字符串
json_str = json.dumps(data)
print("JSON 字符串:", json_str)
# 输出:{"name": "Alice", "age": 30, "is_student": false, "hobbies": ["reading", "hiking"], "address": {"city": "New York", "zipcode": "10001"}, "score": null}
# 格式化输出(更易读)
pretty_json = json.dumps(data, indent=4, ensure_ascii=False)
print("格式化 JSON:")
print(pretty_json)

"""
dumps() 常用参数:
indent:指定缩进空格数,美化输出
ensure_ascii:默认 True(非 ASCII 字符转义),设为 False 可保留中文等字符
sort_keys:设为 True 可按 key 排序
"""

5. 反序列化(JSON → Python)

import json
# JSON 字符串

json_str = '''
{
    "name": "Bob",
    "age": 25,
    "is_student": true,
    "hobbies": ["coding", "gaming"],
    "address": {
        "city": "London",
        "zipcode": "SW1A 1AA"
    },

    "score": null

}
'''
# 使用 loads() 转为 Python 字典
python_data = json.loads(json_str)
print("Python 对象类型:", type(python_data))  # <class 'dict'>
print("姓名:", python_data["name"])          # Bob
print("爱好:", python_data["hobbies"][0])    # coding

6. 与文件交互

import json
data = {"name": "Charlie", "age": 35}
# 序列化并写入文件(dump())
with open("data.json", "w", encoding="utf-8") as f:
    json.dump(data, f, indent=4, ensure_ascii=False)
# 从文件读取并反序列化(load())
with open("data.json", "r", encoding="utf-8") as f:
    loaded_data = json.load(f)
    print("从文件读取的数据:", loaded_data)  # {'name': 'Charlie', 'age': 35}
  1. 处理复杂对象(自定义序列化)

默认情况下,json 模块只能序列化标准 Python 类型。如果需要序列化自定义类对象,需定义 default 函数 或实现类的 __dict__ 方法。

示例:序列化自定义类

import json
class Person:
    def init(self, name, age):
        self.name = name
        self.age = age

# 自定义序列化函数
def person_serializer(obj):
    if isinstance(obj, Person):
        return {"name": obj.name, "age": obj.age, "type": "Person"}
    raise TypeError(f"无法序列化 {type(obj)} 类型的对象")

# 创建自定义对象
person = Person("David", 40)

# 使用 default 参数指定序列化函数
json_str = json.dumps(person, default=person_serializer, indent=4)
print(json_str)

# 输出:
# {
#     "name": "David",
#     "age": 40,
#     "type": "Person"
# }

random模块的随机数生成

1. random 模块: random 模块提供了丰富的随机数生成功能,可用于生成随机整数、浮点数、随机选择序列元素等场景。用户可以根据根据场景选择合适的函数,例如抽奖可用 choice() 或 sample(),洗牌可用 shuffle(),数值模拟可用 gauss() 等。

2. 生成随机浮点数:

  • random.random(): 生成 [0.0, 1.0) 之间的随机浮点数

  • random.uniform(a, b):生成 [a, b] 或 [b, a] 之间的随机浮点数(取决于 a 和 b 的大小)

import random

# 生成 [0.0, 1.0) 之间的随机浮点数

print(random.random())  # 示例:0.783421569

# 生成 [1.5, 3.5] 之间的随机浮点数

print(random.uniform(1.5, 3.5))  # 示例:2.8912345

3. 生成随机整数:

  • random.randint(a, b): 生成 [a, b] 之间的整数(包含 a 和 b)

  • random.randrange(start, stop[, step]): 从指定范围中按步长随机选择整数(类似 range() 用法)

import random
# 生成 1-10 之间的随机整数(包含1和10)
print(random.randint(1, 10))  # 示例:7
# 从 0-20 中随机选择偶数(步长为2)
print(random.randrange(0, 21, 2))  # 示例:14

4. 随机选择元素:

  • random.choice(seq): 从非空序列中随机选择一个元素

  • random.choices(seq, weights=None, k=1): 从序列中随机选择 k 个元素(可带权重,允许重复)

import random
fruits = ["苹果", "香蕉", "橙子", "草莓"]

# 随机选择一个水果
print(random.choice(fruits))  # 示例:香蕉

# 带权重随机选择(草莓被选中概率更高)
print(random.choices(fruits, weights=[1, 1, 1, 3], k=2))  # 示例:['草莓', '橙子']

5. 打乱序列顺序:

  • random.shuffle(seq): 原地打乱序列(修改原序列,无返回值)

import random

nums = [1, 2, 3, 4, 5]

random.shuffle(nums)  # 原地打乱

print(nums)  # 示例:[3, 1, 5, 2, 4]

6. 随机抽样(无重复):

  • random.sample(seq, k): 从序列中随机选择 k 个不重复的元素

import random
cards = ["红桃A", "黑桃K", "方块Q", "梅花J", "大王"]
# 随机抽取2张不重复的牌
print(random.sample(cards, 2))  # 示例:['黑桃K', '梅花J']

7. 随机种子(确保结果可复现):

  • random.seed(a=None): 设置随机数种子,相同种子会生成相同的随机序列(用于调试或复现结果)

import random
# 设置种子
random.seed(10)
print(random.randint(1, 100))  # 结果固定为 73
# 再次设置相同种子,结果相同
random.seed(10)
print(random.randint(1, 100))  # 仍然输出 73

8. 生成高斯分布随机数:

  • random.gauss(mu, sigma): 生成符合高斯分布(正态分布)的随机数,mu 是均值,sigma 是标准差

import random
# 生成均值为0,标准差为1的高斯随机数
print(random.gauss(0, 1))  # 示例:0.283456

注意事项

  • random 模块生成的是**伪随机数**(基于种子的确定性算法),不适用于加密场景

  • 加密级随机数需使用 secrets 模块(Python 3.6+)

  • 多线程环境下,random 模块可能存在线程安全问题,可使用 random.getstate() 和 random.setstate() 保存/恢复状态

结束语

本篇内容到此就结束了,如果你已经很好地理解了本篇的内容,那么恭喜你,你可以自豪的说:“我学过Python了”。是不是有点失望,我学了这么久怎么才是学过,我明明已经会了。回忆一下开头,Python这门语言包含了丰富的标准库,这些标准库构成了Python无所不能的美名。单单学完本篇,你只是拿到了前往各种库的钥匙,所以前方的区域已经对你开放,继续探索吧旅行者\^_^