🐍Python+AI零基础入门

一、Python基础

 官网地址:https://www.python.org/

一、Python 数据存储基础

1.1 变量与对象

概念说明示例
变量 指向内存中对象的"标签" a = 10
对象 存储在内存中的数据实体 10(整数对象)
引用 变量通过引用指向对象 a 指向 10
垃圾回收 没有引用时自动回收 使用 del a 可手动删除引用
# 变量赋值本质是创建引用
a = 10       # a 指向 10
b = a        # b 也指向 10(同一个对象)
print(id(a))  # 输出 a 的内存地址
print(id(b))  # 输出 b 的内存地址(与 a 相同)

1.2 可变 vs 不可变类型

类型是否可变示例
不可变类型 ❌ 不能修改 int, float, str, tuple, frozenset
可变类型 ✅ 可以修改 list, dict, set, bytearray
# 不可变类型:修改会创建新对象
s = "hello"
s = s + " world"  # 创建新字符串,原对象被回收

# 可变类型:修改不会创建新对象
lst = [1, 2, 3]
lst.append(4)      # 在原列表上修改
print(lst)         # [1, 2, 3, 4]

二、运算符

2.1 算数运算符

运算符含义示例结果
+ 加法 / 拼接 3 + 2 "a"+"b" 5 "ab"
- 减法 5 - 3 2
* 乘法 / 重复 3 * 4 "a"*3 12 "aaa"
/ 除法(浮点数) 10 / 3 3.333...
// 整除(向下取整) 10 // 3 3
% 取余(模运算) 10 % 3 1
** 幂运算 2 ** 3 8
# 复合赋值运算符
a = 10
a += 5   # 等价于 a = a + 5
a -= 3   # 等价于 a = a - 3
a *= 2   # 等价于 a = a * 2
a /= 4   # 等价于 a = a / 4
a //= 2  # 等价于 a = a // 2
a %= 3   # 等价于 a = a % 3
a **= 2  # 等价于 a = a ** 2

2.2 比较运算符(返回布尔值)

运算符含义示例
== 等于 3 == 3True
!= 不等于 3 != 4True
> 大于 5 > 3True
< 小于 3 < 5True
>= 大于等于 5 >= 5True
<= 小于等于 3 <= 5True
# 字符串比较(按字典序)
print("apple" < "banana")   # True
print("Hello" == "hello")   # False(大小写敏感)

2.3 逻辑运算符

 
运算符含义示例结果
and 逻辑与(两者都为 True) True and False False
or 逻辑或(至少一个为 True) True or False True
not 逻辑非(取反) not True False
a, b = 5, 10
print(a > 0 and b > 5)   # True
print(a > 10 or b > 5)   # True
print(not (a > 10))      # True

# 短路运算:逻辑运算会在确定结果时停止
def test():
    print("被调用了")
    return True

print(False and test())  # 不会调用 test()(短路)
print(True or test())    # 不会调用 test()(短路)

2.3 逻辑运算符

运算符含义示例结果
and 逻辑与(两者都为 True) True and False False
or 逻辑或(至少一个为 True) True or False True
not 逻辑非(取反) not True False
a, b = 5, 10
print(a > 0 and b > 5)   # True
print(a > 10 or b > 5)   # True
print(not (a > 10))      # True

# 短路运算:逻辑运算会在确定结果时停止
def test():
    print("被调用了")
    return True

print(False and test())  # 不会调用 test()(短路)
print(True or test())    # 不会调用 test()(短路)

2.4 成员运算符

运算符含义示例
in 判断元素是否在序列中 3 in [1, 2, 3]True
not in 判断元素是否不在序列中 4 not in [1, 2, 3]True
python
# 字符串
print("he" in "hello")     # True
print("x" in "hello")      # False

# 列表
print(3 in [1, 2, 3])      # True

# 字典(检查键)
d = {"name": "张三", "age": 25}
print("name" in d)         # True(检查键)
print("张三" in d.values()) # True(检查值)  

2.5 身份运算符

运算符含义示例
is 判断两个变量是否指向同一对象 a is b
is not 判断两个变量是否指向不同对象 a is not b
a = [1, 2, 3]
b = [1, 2, 3]
c = a

print(a == b)   # True(值相等)
print(a is b)   # False(不同对象)
print(a is c)   # True(同一对象)

2.6 运算符优先级(从高到低)

优先级运算符说明
1 () 括号(最高优先级)
2 ** 幂运算
3 *, /, //, % 乘除取余
4 +, - 加减
5 ==, !=, >, <, >=, <= 比较运算符
6 not 逻辑非
7 and 逻辑与
8 or 逻辑或(最低优先级)
# 建议使用括号提高可读性
result = (2 + 3) * 4 ** 2  # 5 * 16 = 80

三、常用内置函数

3.1 数值运算函数

函数说明示例
abs(x) 绝对值 abs(-5)5
pow(x, y) 幂运算 pow(2, 3)8
round(x, n) 四舍五入,保留 n 位小数 round(3.14159, 2)3.14
max(iterable) 最大值 max([1, 5, 3])5
min(iterable) 最小值 min([1, 5, 3])1
sum(iterable) 求和 sum([1, 2, 3])6
len(iterable) 长度/元素个数 len("hello")5
type(obj) 获取对象类型 type(10)<class 'int'>
id(obj) 获取对象内存地址 id(a)140736123456

3.2 类型转换函数

函数说明示例
int(x) 转换为整数 int("123")123
float(x) 转换为浮点数 float("3.14")3.14
str(x) 转换为字符串 str(123)"123"
bool(x) 转换为布尔值 bool(0)False
list(iterable) 转换为列表 list("abc")['a','b','c']
tuple(iterable) 转换为元组 tuple([1,2,3])(1,2,3)
set(iterable) 转换为集合(去重) set([1,2,2,3]){1,2,3}
dict(iterable) 转换为字典 dict([('a',1)]){'a':1}

3.3 输入输出函数

 
函数说明示例
print(*objects) 打印输出 print("Hello", 123)
input(prompt) 获取用户输入(返回字符串) name = input("请输入:")
# print 高级用法
print("a", "b", "c", sep="-")  # a-b-c
print("Hello", end=" ")        # 不换行
print("World")                 # Hello World

四、字符串运算

运算符/方法说明示例
+ 字符串拼接 "Hello" + " World""Hello World"
* 字符串重复 "Ha" * 3"HaHaHa"
in 检查子串 "he" in "hello"True
[] 索引访问 "hello"[1]"e"
[:] 切片 "hello"[1:4]"ell"
len() 获取长度 len("hello")5

五、列表运算

运算符/方法说明示例
+ 列表拼接 [1,2] + [3,4][1,2,3,4]
* 列表重复 [1,2] * 3[1,2,1,2,1,2]
in 检查元素 3 in [1,2,3]True
[] 索引访问 [1,2,3][1]2
[:] 切片(返回新列表) [1,2,3,4][1:3][2,3]
len() 获取长度 len([1,2,3])3
max()/min() 最大/最小值 max([1,5,3])5
sum() 求和(元素必须为数字) sum([1,2,3])6

六、集合运算(集合特有)

运算符含义方法示例
& 交集 intersection() {1,2,3} & {2,3,4}{2,3}
| 并集 union() {1,2,3} | {3,4,5}{1,2,3,4,5}
- 差集 difference() {1,2,3} - {2,3}{1}
^ 对称差集 symmetric_difference() {1,2,3} ^ {3,4}{1,2,4}
<= 子集 issubset() {1,2} <= {1,2,3}True
>= 超集 issuperset() {1,2,3} >= {1,2}True

七、字典运算

运算符/方法说明示例
in 检查键是否存在 "name" in dTrue
d[key] 访问值(键不存在报错) d["name"]"张三"
d.get(key, default) 安全访问(不存在返回默认值) d.get("age", 0)25
d[key] = value 添加或修改键值对 d["city"] = "北京"
del d[key] 删除键值对 del d["age"]
len(d) 获取键值对数量 len(d)2
| (3.9+) 合并字典 d1 | d2

八、数据存储与运算对比总结表

数据类型可变性有序性索引切片加法运算乘法运算in 操作
列表 list ✅ 可变 ✅ 有序 ✅ 拼接 ✅ 重复 ✅ 检查元素
字符串 str ❌ 不可变 ✅ 有序 ✅ 拼接 ✅ 重复 ✅ 检查子串
元组 tuple ❌ 不可变 ✅ 有序 ✅ 拼接 ✅ 重复 ✅ 检查元素
集合 set ✅ 可变 ❌ 无序 ✅ 检查元素
字典 dict ✅ 可变 ✅ 有序(3.7+) ❌(用键访问) ✅ 检查键

九、内存管理要点

 
概念说明
引用计数 每个对象记录被引用的次数,归零时回收
垃圾回收 Python 自动回收不再使用的内存
小整数池 -5256 的整数在 Python 启动时预先创建,所有变量共享同一对象
字符串驻留 某些字符串会被缓存以节省内存
深浅拷贝 浅拷贝只复制顶层,深拷贝递归复制所有层级
# 小整数池示例
a = 10
b = 10
print(a is b)   # True(指向同一对象)

c = 257
d = 257
print(c is d)   # False(超出小整数池,创建了新对象)

# 浅拷贝 vs 深拷贝
import copy
lst1 = [[1, 2], [3, 4]]
lst2 = lst1.copy()           # 浅拷贝
lst3 = copy.deepcopy(lst1)   # 深拷贝
lst1[0][0] = 999
print(lst2)  # [[999, 2], [3, 4]](浅拷贝受影响)
print(lst3)  # [[1, 2], [3, 4]](深拷贝不受影响)

十、运算符总结表

类型运算符说明
算术 + - * / // % ** 数学运算
比较 == != > < >= <= 返回布尔值
逻辑 and or not 布尔逻辑
成员 in not in 检查元素是否存在
身份 is is not 检查对象身份(内存地址)
位运算 & | ^ ~ << >> 二进制位操作(不常用)
赋值 = += -= *= /= //= %= **= 赋值操作

二、Python数据容器

一、列表(list)

特点:有序、可变、可重复、支持索引

1.1 创建列表

# 空列表
lst1 = []
lst2 = list()

# 带元素
lst3 = [1, 2, 3, 4, 5]
lst4 = ["a", "b", "c"]
lst5 = [1, "hello", 3.14, True]  # 混合类型
lst6 = list("hello")  # ['h', 'e', 'l', 'l', 'o']

# 列表推导式
lst7 = [x**2 for x in range(5)]  # [0, 1, 4, 9, 16]

1.2 增删改查

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

# 查(索引和切片)
print(lst[0])       # 1(索引从0开始)
print(lst[-1])      # 5(倒数第一个)
print(lst[1:4])     # [2, 3, 4](切片,左闭右开)
print(lst[::2])     # [1, 3, 5](步长)

# 增
lst.append(6)       # [1, 2, 3, 4, 5, 6](末尾添加)
lst.insert(0, 0)    # [0, 1, 2, 3, 4, 5, 6](指定位置插入)
lst.extend([7, 8])  # [0, 1, 2, 3, 4, 5, 6, 7, 8](合并列表)

# 改
lst[0] = 100        # [100, 1, 2, 3, 4, 5, 6, 7, 8]

# 删
lst.remove(100)     # 移除指定元素
lst.pop()           # 移除并返回最后一个元素
lst.pop(0)          # 移除并返回指定位置元素
del lst[0]          # 删除指定位置元素
lst.clear()         # 清空列表

二、字符串(str)

特点:有序、不可变、可索引

2.1 创建字符串

s1 = "hello"
s2 = 'world'
s3 = """多行
字符串"""
s4 = str(123)  # "123"
s5 = " ".join(["a", "b", "c"])  # "a b c" 

2.2 查(索引和切片)

s = "Hello World"

print(s[0])       # H
print(s[-1])      # d
print(s[1:4])     # ell
print(s[::2])     # HloWrd
print(s[::-1])    # dlroW olleH(反转)

2.3 常用方法

s = "  Hello World  "

# 大小写转换
print(s.lower())      # "  hello world  "
print(s.upper())      # "  HELLO WORLD  "
print(s.title())      # "  Hello World  "
print(s.swapcase())   # "  hELLO wORLD  "

# 去除空白
print(s.strip())      # "Hello World"(去除两端)
print(s.lstrip())     # "Hello World  "(去除左端)
print(s.rstrip())     # "  Hello World"(去除右端)

# 查找和替换
print(s.find("World"))   # 7(返回索引,找不到返回-1)
print(s.index("World"))  # 7(找不到报错)
print(s.count("l"))      # 3
print(s.replace("World", "Python"))  # "  Hello Python  "

# 分割和拼接
print("a,b,c".split(","))   # ['a', 'b', 'c']
print("a b c".split())      # ['a', 'b', 'c']
print("-".join(["a", "b"])) # "a-b"

# 判断方法
print(s.isalnum())   # False(包含空格)
print(s.isalpha())   # False(包含空格)
print(s.isdigit())   # False
print("123".isdigit())  # True
print("hello".startswith("he"))  # True
print("hello".endswith("lo"))    # True

# 填充和对齐
print("5".zfill(3))      # "005"
print("abc".center(10))  # "   abc    "
print("abc".ljust(10))   # "abc       "
print("abc".rjust(10))   # "       abc"

三、元组(tuple)

特点:有序、不可变、可重复

2.1 创建元组

t1 = ()               # 空元组
t2 = (1,)             # 单个元素(必须加逗号)
t3 = (1, 2, 3, 4, 5)
t4 = tuple([1, 2, 3]) # (1, 2, 3)
t5 = 1, 2, 3          # (1, 2, 3)(省略括号)

2.2 查(索引和切片)

t = (1, 2, 3, 4, 5)

print(t[0])       # 1
print(t[-1])      # 5
print(t[1:4])     # (2, 3, 4)
print(len(t))     # 5
print(max(t))     # 5
print(min(t))     # 1
print(sum(t))     # 15
print(t.index(3)) # 2
print(t.count(2)) # 1

2.3 元组的不可变性

t = (1, 2, 3)
# t[0] = 100  # ❌ 报错!元组不可变

# 修改元组需要创建新元组
t = t + (4, 5)  # (1, 2, 3, 4, 5)
t = t * 2       # (1, 2, 3, 4, 5, 1, 2, 3, 4, 5)

# 元组解包
a, b, c = (1, 2, 3)  # a=1, b=2, c=3

四、集合(set)

特点:无序、可变、元素唯一

4.1. 创建集合

s1 = set()              # 空集合(注意:{} 是空字典)
s2 = {1, 2, 3, 4, 5}
s3 = set([1, 2, 2, 3])  # {1, 2, 3}(自动去重)
s4 = set("hello")       # {'h', 'e', 'l', 'o'}(顺序不确定)

4.2 增删改查

s = {1, 2, 3}

# 增
s.add(4)          # {1, 2, 3, 4}
s.update([5, 6])  # {1, 2, 3, 4, 5, 6}

# 删
s.remove(3)       # 移除3,不存在报错
s.discard(10)     # 移除10,不存在不报错
s.pop()           # 随机移除并返回一个元素
s.clear()         # 清空集合

# 查(集合不能通过索引访问,只能遍历)
for item in s:
    print(item)

4.3 集合计算

s1 = {1, 2, 3, 4}
s2 = {3, 4, 5, 6}

# 交集
print(s1 & s2)              # {3, 4}
print(s1.intersection(s2))  # {3, 4}

# 并集
print(s1 | s2)              # {1, 2, 3, 4, 5, 6}
print(s1.union(s2))         # {1, 2, 3, 4, 5, 6}

# 差集
print(s1 - s2)              # {1, 2}
print(s1.difference(s2))    # {1, 2}
print(s2 - s1)              # {5, 6}

# 对称差集
print(s1 ^ s2)              # {1, 2, 5, 6}
print(s1.symmetric_difference(s2))  # {1, 2, 5, 6}

# 子集和超集
print({1, 2}.issubset(s1))   # True
print(s1.issuperset({1, 2})) # True
print(s1.isdisjoint({5, 6})) # False(有交集)

五、字典(dict)

特点:无序(Python 3.7+ 有序)、可变、键值对、键唯一

5.1. 创建字典

# 空字典
d1 = {}
d2 = dict()

# 带元素
d3 = {"name": "张三", "age": 25, "city": "北京"}
d4 = dict(name="张三", age=25, city="北京")
d5 = dict([("name", "张三"), ("age", 25)])  # 从列表创建

# 字典推导式
d6 = {x: x**2 for x in range(5)}  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

5.2 增删改查

d = {"name": "张三", "age": 25}

# 查
print(d["name"])          # 张三(键存在)
print(d.get("city"))      # None(键不存在返回None)
print(d.get("city", "未知"))  # "未知"(自定义默认值)
print(d.keys())           # dict_keys(['name', 'age'])
print(d.values())         # dict_values(['张三', 25])
print(d.items())          # dict_items([('name', '张三'), ('age', 25)])

# 增和改
d["city"] = "北京"        # 新增键值对
d["age"] = 26             # 修改已有键的值
d.update({"gender": "男", "age": 27})  # 批量更新

# 删
del d["gender"]           # 删除指定键
age = d.pop("age")        # 删除并返回指定键的值
item = d.popitem()        # 删除并返回最后一个键值对
d.clear()                 # 清空字典

5.3 遍历字典

d = {"name": "张三", "age": 25, "city": "北京"}

# 遍历键
for key in d:
    print(key, d[key])

# 遍历键值对
for key, value in d.items():
    print(key, value)

# 遍历值
for value in d.values():
    print(value)

5.4 其他常用操作

d = {"name": "张三", "age": 25}

print(len(d))           # 2
print("name" in d)      # True(检查键是否存在)
print("gender" in d)    # False

# 合并字典(Python 3.9+)
d1 = {"a": 1, "b": 2}
d2 = {"c": 3, "d": 4}
merged = {**d1, **d2}   # {'a': 1, 'b': 2, 'c': 3, 'd': 4}
# merged = d1 | d2     # Python 3.9+

# 设置默认值
d.setdefault("gender", "男")  # 键存在返回原值,不存在设置新值

六、相互转换

6.1 列表 ↔ 其他类型

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

# 列表 → 字符串
s = str(lst)        # "[1, 2, 3, 4, 5]"
s = ",".join(map(str, lst))  # "1,2,3,4,5"

# 列表 → 元组
t = tuple(lst)      # (1, 2, 3, 4, 5)

# 列表 → 集合(去重)
s = set(lst)        # {1, 2, 3, 4, 5}

# 列表 → 字典(需要键值对)
lst2 = [("a", 1), ("b", 2)]
d = dict(lst2)      # {'a': 1, 'b': 2}

6.2 字符串 ↔ 其他类型

s = "hello"

# 字符串 → 列表
lst = list(s)       # ['h', 'e', 'l', 'l', 'o']
lst = s.split()     # ['hello']

# 字符串 → 元组
t = tuple(s)        # ('h', 'e', 'l', 'l', 'o')

# 字符串 → 集合
s = set(s)          # {'h', 'e', 'l', 'o'}

# 字符串 → 字典(需要解析)
import json
d = json.loads('{"name": "张三"}')  # {'name': '张三'}

6.3 元组 ↔ 其他类型

t = (1, 2, 3, 4, 5)

# 元组 → 列表
lst = list(t)       # [1, 2, 3, 4, 5]

# 元组 → 集合
s = set(t)          # {1, 2, 3, 4, 5}

# 元组 → 字符串
s = str(t)          # "(1, 2, 3, 4, 5)"

6.4 集合 ↔ 其他类型

s = {1, 2, 3, 4, 5}

# 集合 → 列表
lst = list(s)       # [1, 2, 3, 4, 5](顺序不确定)

# 集合 → 元组
t = tuple(s)        # (1, 2, 3, 4, 5)

# 集合 → 字符串
s_str = str(s)      # "{1, 2, 3, 4, 5}"

6.5 字典 ↔ 其他类型

d = {"a": 1, "b": 2}

# 字典 → 列表
keys = list(d.keys())      # ['a', 'b']
values = list(d.values())  # [1, 2]
items = list(d.items())    # [('a', 1), ('b', 2)]

# 字典 → 字符串
s = str(d)          # "{'a': 1, 'b': 2}"
s = json.dumps(d)   # '{"a": 1, "b": 2}'(JSON格式)

# 字典 → 其他类型需要提取值或键

七、总结对比及选用指南

特性列表 list字符串 str元组 tuple集合 set字典 dict
有序性 ✅ 有序 ✅ 有序 ✅ 有序 ❌ 无序 ✅ 有序(3.7+)
可变性 ✅ 可变 ❌ 不可变 ❌ 不可变 ✅ 可变 ✅ 可变
元素唯一 ❌ 可重复 ❌ 可重复 ❌ 可重复 ✅ 唯一 ✅ 键唯一
索引支持 ✅(键)
切片支持
适用场景 通用序列 文本处理 不可变序列 去重、集合运算 键值映射

 

场景推荐类型原因
存储有序数据且需要修改 列表 灵活,支持增删改
存储不可变的有序数据 元组 安全,性能好
文本处理 字符串 丰富的字符串方法
去重或集合运算 集合 自动去重,集合运算快
键值映射/查找 字典 通过键快速查找

三、Python传参

一、参数传递的底层原理

1.1 传递方式本质:对象引用传递(传对象引用)

Python 的参数传递既不是"值传递"也不是"引用传递",而是"对象引用传递"(Pass by Object Reference)。

概念说明
不可变对象 函数内修改参数会创建新对象,不影响外部变量
可变对象 函数内修改参数会直接影响外部变量
# 不可变对象(int, str, tuple 等)
def modify_num(x):
    x = x + 10
    print("函数内:", x)  # 20

a = 10
modify_num(a)
print("函数外:", a)     # 10(不变)

# 可变对象(list, dict, set 等)
def modify_list(lst):
    lst.append(4)
    print("函数内:", lst)  # [1, 2, 3, 4]

my_list = [1, 2, 3]
modify_list(my_list)
print("函数外:", my_list)  # [1, 2, 3, 4](被修改)

二、Python 中的 5 种传参方式

2.1 位置参数(Positional Arguments)

定义:调用函数时按定义顺序传入参数,参数个数和顺序必须匹配。

def greet(name, age, city):
    print(f"{name}, {age}岁, 来自{city}")

# 正确:按顺序传参
greet("张三", 25, "北京")

# 错误:顺序不对会导致逻辑错误
greet("北京", 25, "张三")  # 语义错误

2.2 关键字参数(Keyword Arguments)

定义:调用时通过参数名指定传入的值,顺序可以任意。

def greet(name, age, city):
    print(f"{name}, {age}岁, 来自{city}")

# 使用关键字参数
greet(name="张三", city="北京", age=25)
greet(city="上海", age=30, name="李四")

2.3 默认参数(Default Arguments)

定义:在函数定义时为参数提供默认值,调用时可以不传该参数。

def greet(name, age=18, city="北京"):
    print(f"{name}, {age}岁, 来自{city}")

# 使用默认参数
greet("张三")              # 张三, 18岁, 来自北京
greet("李四", 25)          # 李四, 25岁, 来自北京
greet("王五", city="上海") # 王五, 18岁, 来自上海

⚠️ 默认参数的陷阱:默认参数在函数定义时只计算一次,如果默认值是可变对象(如列表),可能会产生意外行为。

# ❌ 错误示例:使用可变对象作为默认值
def add_item(item, lst=[]):
    lst.append(item)
    return lst

print(add_item(1))  # [1]
print(add_item(2))  # [1, 2](意外!)
print(add_item(3))  # [1, 2, 3](意外!)

# ✅ 正确做法
def add_item(item, lst=None):
    if lst is None:
        lst = []
    lst.append(item)
    return lst

print(add_item(1))  # [1]
print(add_item(2))  # [2](独立)
print(add_item(3))  # [3](独立)

2.4 可变位置参数(*args

定义:收集所有多余的位置参数,打包成一个元组

def sum_all(*args):
    print("参数类型:", type(args))  # <class 'tuple'>
    print("参数内容:", args)
    return sum(args)

print(sum_all(1, 2, 3))       # 6
print(sum_all(10, 20, 30, 40)) # 100
print(sum_all())              # 0(可以传0个)

2.5 可变关键字参数(**kwargs

定义:收集所有多余的关键字参数,打包成一个字典

def print_info(**kwargs):
    print("参数类型:", type(kwargs))  # <class 'dict'>
    print("参数内容:", kwargs)
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="张三", age=25, city="北京")
print_info()  # 可以传0个

三、参数组合顺序

当多种参数类型同时使用时,必须遵循以下固定顺序

1. 位置参数(必选参数)
2. *args(可变位置参数)
3. 默认参数(关键字参数)
4. **kwargs(可变关键字参数)
def demo(a, b, *args, c=10, d=20, **kwargs):
    print(f"a={a}, b={b}")
    print(f"args={args}")
    print(f"c={c}, d={d}")
    print(f"kwargs={kwargs}")

demo(1, 2, 3, 4, 5, c=100, e=50, f=60)
# 输出:
# a=1, b=2
# args=(3, 4, 5)
# c=100, d=20
# kwargs={'e': 50, 'f': 60}

四、参数解包(Unpacking)

4.1 解包列表/元组(*

def add(a, b, c):
    return a + b + c

nums = [1, 2, 3]
print(add(*nums))  # 6

# 元组解包
tup = (4, 5, 6)
print(add(*tup))   # 15

4.2 解包字典(**

def greet(name, age, city):
    print(f"{name}, {age}岁, 来自{city}")

person = {"name": "张三", "age": 25, "city": "北京"}
greet(**person)  # 张三, 25岁, 来自北京

4.3 混合解包

def func(a, b, c, d=10, e=20):
    print(f"a={a}, b={b}, c={c}, d={d}, e={e}")

args = [1, 2, 3]
kwargs = {"d": 100, "e": 200}
func(*args, **kwargs)  # a=1, b=2, c=3, d=100, e=200

五、/* 分隔符

5.1 / 分隔符(Python 3.8+)

  • / 之前的参数:只能按位置传递(positional-only)

  • / 之后的参数:可以按位置或关键字传递

def func(a, b, /, c, d):
    print(a, b, c, d)

func(1, 2, 3, 4)            # ✅ 正确
func(1, 2, c=3, d=4)        # ✅ 正确
func(a=1, b=2, c=3, d=4)    # ❌ 错误:a 和 b 不能使用关键字参数

5.2 * 分隔符

  • * 之前的参数:可以按位置或关键字传递

  • * 之后的参数:只能按关键字传递(keyword-only)

def func(a, b, *, c, d):
    print(a, b, c, d)

func(1, 2, c=3, d=4)        # ✅ 正确
func(1, 2, 3, 4)            # ❌ 错误:c 和 d 必须使用关键字参数

5.3 同时使用 /*

def func(a, b, /, c, *, d, e):
    print(a, b, c, d, e)

func(1, 2, 3, d=4, e=5)     # ✅ 正确
# func(1, 2, c=3, d=4, e=5) # ❌ 错误:a 和 b 不能使用关键字
# func(1, 2, 3, 4, 5)       # ❌ 错误:d 和 e 必须使用关键字

六、参数传递方式对比表

传参方式定义语法调用语法示例特点
位置参数 def f(a, b): f(1, 2) f(1, 2) 按顺序传参
关键字参数 def f(a, b): f(a=1, b=2) f(b=2, a=1) 按名称传参,可调换顺序
默认参数 def f(a, b=10): f(1) f(1) 参数有默认值,可省略
可变位置参数 def f(*args): f(1, 2, 3) f(1, 2, 3, 4, 5) 接收任意数量位置参数
可变关键字参数 def f(**kwargs): f(a=1, b=2) f(name="张三", age=25) 接收任意数量关键字参数
位置只传 def f(a, b, /): f(1, 2) f(1, 2) / 前只能按位置传参
关键字只传 def f(*, a, b): f(a=1, b=2) f(a=1, b=2) * 后只能按关键字传参

七、常见使用场景

场景1:不确定参数个数 → 使用 *args

def max_number(*args):
    if not args:
        return None
    return max(args)

print(max_number(1, 5, 3, 9, 2))  # 9

场景2:需要接收任意关键字参数 → 使用 **kwargs

def save_user_info(**kwargs):
    for key, value in kwargs.items():
        print(f"保存 {key}: {value}")

save_user_info(name="张三", age=25, email="zhangsan@email.com")

场景3:装饰器 → 使用 *args, **kwargs

def timer(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        print(f"执行时间: {time.time() - start:.4f}秒")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(1)

slow_function()

场景4:强制使用关键字参数(提高代码可读性)

def create_user(name, *, age, city):
    print(f"创建用户: {name}, {age}岁, 来自{city}")

create_user("张三", age=25, city="北京")  # ✅ 强制使用关键字
# create_user("张三", 25, "北京")        # ❌ 错误

八、argskwargs 命名惯例

命名含义说明
*args arguments 位置参数元组(可自定义,如 *params
**kwargs keyword arguments 关键字参数字典(可自定义,如 **options
# 自定义名称(不推荐)
def func(*params, **options):
    pass

# 标准命名(推荐)
def func(*args, **kwargs):
    pass

九、参数传递优先级总结

调用函数时,Python 按照以下顺序解析参数:

def demo(a, b, *args, c=10, d=20, **kwargs):
    pass

demo(1, 2, 3, 4, 5, c=100, e=50, f=60)
  1. 位置参数a=1, b=2

  2. *args:收集多余的位置参数 (3, 4, 5)

  3. 默认参数c=100(覆盖默认值 10),d=20

  4. **kwargs:收集多余的关键字参数 {'e': 50, 'f': 60}

四、Python高级

一、类型注解

1.1 基本概念

类型注解(Type Hints)是Python 3.5+引入的功能,用于声明变量、函数参数和返回值的预期类型

# 没有类型注解
def greet(name):
    return f"Hello, {name}"

# 有类型注解
def greet(name: str) -> str:
    return f"Hello, {name}"

2.1 基础数据类型注解

# 整数
age: int = 25

# 浮点数
price: float = 99.99

# 字符串
name: str = "张三"

# 布尔值
is_active: bool = True

# 字节
data: bytes = b"hello"

# None
result: None = None

注解的多种写法

# 方式1:变量名: 类型 = 值
name: str = "Alice"

# 方式2:变量名: 类型(不赋值)
age: int

# 方式3:直接赋值(类型推断)
city = "北京"  # IDE会自动推断为str类型

2.3 容器类型注解

列表(List)

from typing import List

# Python 3.9+ 可以直接使用 list
# 旧版本需要 from typing import List

# 整数列表
numbers: list[int] = [1, 2, 3, 4, 5]

# 字符串列表
names: list[str] = ["张三", "李四", "王五"]

# 混合类型列表
mixed: list[int | str] = [1, "hello", 2, "world"]

# 嵌套列表
matrix: list[list[int]] = [[1, 2], [3, 4]]

# 任意类型列表
any_list: list = [1, "a", True]  # 不推荐

元组(Tuple)  

from typing import Tuple

# 固定长度元组
user: tuple[str, int] = ("张三", 25)  # 2个元素
point: tuple[int, int] = (10, 20)    # 2个整数
person: tuple[str, int, float] = ("李四", 30, 1.75)

# 可变长度元组
scores: tuple[int, ...] = (90, 85, 88, 92)  # 任意数量整数

# 空元组
empty: tuple = ()

# 单元素元组(注意逗号)
single: tuple[int] = (5,)  # 类型是tuple[int],而不是int

字典(Dict) 

from typing import Dict

# Python 3.9+
# 字符串键,整数值
scores: dict[str, int] = {"数学": 95, "英语": 88, "语文": 92}

# 字符串键,字符串值
config: dict[str, str] = {"host": "localhost", "port": "8080"}

# 整数键,列表值
data: dict[int, list[str]] = {
    1: ["苹果", "香蕉"],
    2: ["橙子", "葡萄"]
}

# 复杂的嵌套字典
user_data: dict[str, dict[str, int | str]] = {
    "张三": {"age": 25, "score": 95},
    "李四": {"age": 30, "score": 88}
}

集合(Set)

2.4 参数注解及返回值注解  

# 参数注解和返回值注解
def calculate_area(length: float, width: float) -> float:
    """计算矩形面积"""
    return length * width

# 没有返回值
def log_message(msg: str) -> None:
    print(f"[LOG] {msg}")

# 多参数
def create_user(name: str, age: int, email: str = "") -> dict[str, str | int]:
    return {"name": name, "age": age, "email": email} 

二、模块

 一、模块的定义及使用

模块中import和from区别与联系

一句话说清楚核心区别:import 是“连人带家伙全请进来”from...import 是“只请某个人进来,不用带他的家当”。

假设你有个工具包(模块)叫 小明,里面有一把锤子 hanmer 和一个扳手 wrench。
import 小明:你把小明整个工具箱搬进你家。
    用的时候得说:小明.锤子、小明.扳手。
    好处:你知道这工具是小明的,不会和自家的东西搞混。


from 小明 import 锤子:你只把锤子拿出来放自己兜里。
    用的时候直接说:锤子。
    好处:打字快,代码简洁。
    坏处:如果自家也有个叫“锤子”的东西,就会覆盖掉,容易出问题。

代码层面区别

math_utils.py:

# math_utils.py
def add(a, b):
    return a + b

def multiply(a, b):
    return a * b

import方式:import math_utils

import math_utils

# 必须用模块名.函数名 的方式调用
result1 = math_utils.add(1, 2)      # ✅ 正确
result2 = math_utils.multiply(3, 4) # ✅ 正确

# 下面这种写法会报错(找不到 add)
# result = add(1, 2)  # ❌ NameError: name 'add' is not defined

from方式:from math_utils import add

from math_utils import add

# 可以直接用函数名调用,不用加前缀
result = add(1, 2)  # ✅ 正确

# 但 multiply 没被导入,用不了
# result = multiply(3, 4)  # ❌ NameError

通配符导入:from math_utils import *

from math_utils import *

# 模块里所有的东西都直接拿出来
result1 = add(1, 2)      # ✅
result2 = multiply(3, 4) # ✅

使用场景对比

  • import 模块:把整个模块请进来,调用时加前缀 模块.,安全、清晰

  • from 模块 import 东西:只把部分功能拿进来,直接调用,简洁、方便,但注意命名冲突

新手建议:在不确定是否会冲突时,先用 import 模块,更安全,也更容易看懂代码。

场景推荐写法原因
只用模块里的1-2个函数 from 模块 import 函数名 代码简洁,少打几个字
要用模块里的很多功能 import 模块 防止函数名冲突,一看就知道来自哪个模块
两个库有同名函数 必须用 import 模块 例如 os.pathPath,不区分会覆盖
写大型项目/团队协作 推荐 import 模块 代码可读性强,明确来源
交互式命令行(随手测试) 可以用 from...import 方便快捷

 __all__关键字

__all__ 是 Python 中一个特殊的模块级变量,用于控制 from module import * 时哪些内容会被导入。它本质上是一个白名单,显式声明模块对外公开的接口。

示例:mymodule.py

# mymodule.py

# 对外公开的接口
__all__ = ["public_func", "PublicClass"]

def public_func():
    print("这是公开函数")

def _private_func():
    print("这是私有函数(以下划线开头)")

class PublicClass:
    pass

class _PrivateClass:
    pass

# 未在 __all__ 中列出的函数
def hidden_func():
    print("这个函数不会在 import * 中被导入")

使用

# 在另一个文件中
from mymodule import *

public_func()           # ✅ 可以调用
obj = PublicClass()     # ✅ 可以实例化

# hidden_func()         # ❌ NameError: 未定义(不在 __all__ 中)
# _private_func()       # ❌ NameError: 未定义
导入方式__all__ 是否生效导入内容
from module import * ✅ 生效 只导入 __all__ 中列出的名称
from module import name ❌ 不生效 只导入指定的 name
import module ❌ 不生效 导入整个模块,通过 module.xxx 访问
# __all__ 只影响 from ... import * 这一种导入方式!
import mymodule
mymodule.hidden_func()   # ✅ 可以访问(模块本身被完整加载)

二、Python 常用内置模块及功能

模块主要用途常用函数/类
json JSON 数据处理 dumps, loads, dump, load
pickle Python 对象序列化 dumps, loads, dump, load
csv CSV 文件读写 reader, writer, DictReader
os 操作系统接口 listdir, mkdir, path.join
sys 解释器相关 argv, exit, path
shutil 高级文件操作 copy, copytree, rmtree
glob 文件通配符 glob
datetime 日期时间 now, strftime, timedelta
time 时间操作 time, sleep, perf_counter
math 数学函数 sqrt, ceil, floor, pi
random 随机数生成 randint, choice, shuffle
statistics 统计函数 mean, median, stdev
re 正则表达式 match, search, findall
collections 高级容器 defaultdict, Counter, deque
itertools 迭代器工具 chain, product, combinations
urllib URL 处理 urlopen, urlencode
logging 日志记录 info, error, basicConfig
hashlib 哈希算法 md5, sha256
copy 对象拷贝 copy, deepcopy
typing 类型注解 List, Dict, Optional

json——JSON 数据编解码

函数说明示例
json.dumps(obj) 将 Python 对象转为 JSON 字符串 json.dumps({"a": 1})'{"a": 1}'
json.loads(json_str) 将 JSON 字符串转为 Python 对象 json.loads('{"a": 1}'){'a': 1}
json.dump(obj, file) 将 Python 对象写入文件(JSON 格式) json.dump(data, f)
json.load(file) 从 JSON 文件读取数据 data = json.load(f)
import json

# 编码
data = {"name": "张三", "age": 25, "hobbies": ["读书", "跑步"]}
json_str = json.dumps(data, ensure_ascii=False, indent=2)
print(json_str)

# 解码
restored = json.loads(json_str)
print(restored["name"])  # 张三

# 读写文件
with open("data.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

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

pickle-----Python对象序列化

函数说明示例
pickle.dumps(obj) 将 Python 对象序列化为字节串 pickle.dumps([1,2,3])
pickle.loads(bytes) 从字节串反序列化 Python 对象 pickle.loads(data)
pickle.dump(obj, file) 将 Python 对象写入文件 pickle.dump(obj, f)
pickle.load(file) 从文件读取 Python 对象 obj = pickle.load(f)
import pickle

data = {"name": "张三", "scores": [85, 92, 78]}

# 序列化到文件
with open("data.pkl", "wb") as f:
    pickle.dump(data, f)

# 从文件读取
with open("data.pkl", "rb") as f:
    loaded = pickle.load(f)
print(loaded)  # {'name': '张三', 'scores': [85, 92, 78]}

csv----CSV文件读写

函数/类说明示例
csv.reader(file) 创建 CSV 读取器 reader = csv.reader(f)
csv.writer(file) 创建 CSV 写入器 writer = csv.writer(f)
csv.DictReader(file) 读取为字典(首行为表头) reader = csv.DictReader(f)
csv.DictWriter(file, fieldnames) 写入字典数据 writer = csv.DictWriter(f, fieldnames)
import csv

# 写入 CSV
with open("students.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerow(["姓名", "年龄", "城市"])
    writer.writerow(["张三", 25, "北京"])
    writer.writerow(["李四", 30, "上海"])

# 读取 CSV
with open("students.csv", "r", encoding="utf-8") as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

# DictReader 方式(首行为表头)
with open("students.csv", "r", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(row["姓名"], row["年龄"])

os----操作系统接口

函数说明示例
os.getcwd() 获取当前工作目录 os.getcwd()'/home/user'
os.chdir(path) 切换工作目录 os.chdir("/tmp")
os.listdir(path) 列出目录内容 os.listdir(".")['file1.py', 'dir1']
os.mkdir(path) 创建单级目录 os.mkdir("new_folder")
os.makedirs(path) 创建多级目录 os.makedirs("a/b/c")
os.remove(path) 删除文件 os.remove("file.txt")
os.rmdir(path) 删除空目录 os.rmdir("empty_dir")
os.removedirs(path) 删除多级空目录 os.removedirs("a/b/c")
os.rename(old, new) 重命名文件/目录 os.rename("old.txt", "new.txt")
os.path.exists(path) 判断路径是否存在 os.path.exists("file.txt")True
os.path.isfile(path) 判断是否是文件 os.path.isfile("file.txt")True
os.path.isdir(path) 判断是否是目录 os.path.isdir("folder")True
os.path.join(a, b) 拼接路径 os.path.join("dir", "file.txt")'dir/file.txt'
os.path.basename(path) 获取文件名 os.path.basename("/a/b/c.txt")'c.txt'
os.path.dirname(path) 获取目录名 os.path.dirname("/a/b/c.txt")'/a/b'
os.path.splitext(path) 分离文件名和扩展名 os.path.splitext("file.txt")('file', '.txt')
os.environ 获取环境变量 os.environ.get("PATH")
import os

# 当前目录
print(os.getcwd())

# 创建目录
os.makedirs("data/2024/01", exist_ok=True)

# 遍历目录
for filename in os.listdir("."):
    if filename.endswith(".py"):
        print(f"Python 文件: {filename}")

# 路径操作
path = os.path.join("data", "2024", "01", "report.txt")
print(os.path.basename(path))   # report.txt
print(os.path.dirname(path))    # data/2024/01
print(os.path.splitext(path))   # ('data/2024/01/report', '.txt')

sys----Python解释器相关

函数/属性说明示例
sys.argv 命令行参数列表 sys.argv[0] 是脚本名
sys.exit(code) 退出程序 sys.exit(0)
sys.path 模块搜索路径列表 sys.path.append("/my/modules")
sys.version Python 版本信息 sys.version'3.12.0'
sys.platform 操作系统平台 sys.platform'win32' / 'linux'
sys.stdin 标准输入 sys.stdin.read()
sys.stdout 标准输出 sys.stdout.write("Hello")
sys.stderr 标准错误 sys.stderr.write("Error!")
sys.getsizeof(obj) 获取对象内存大小(字节) sys.getsizeof([1,2,3])
import sys

# 命令行参数
# python script.py arg1 arg2
print(f"脚本名: {sys.argv[0]}")
print(f"参数: {sys.argv[1:]}")

# 添加模块搜索路径
sys.path.append("/custom/modules")

# 获取 Python 版本
print(f"Python 版本: {sys.version}")

# 退出程序
if len(sys.argv) < 2:
    print("请提供参数!")
    sys.exit(1)

shutil----高级文件操作

函数说明示例
shutil.copy(src, dst) 复制文件 shutil.copy("a.txt", "b.txt")
shutil.copytree(src, dst) 递归复制目录 shutil.copytree("src_dir", "dst_dir")
shutil.move(src, dst) 移动文件/目录 shutil.move("a.txt", "new_dir/")
shutil.rmtree(path) 递归删除目录 shutil.rmtree("folder")
shutil.make_archive(base, format, root) 创建压缩包 shutil.make_archive("backup", "zip", "data/")
shutil.disk_usage(path) 获取磁盘使用情况 shutil.disk_usage("/")
import shutil

# 复制文件
shutil.copy("source.txt", "backup.txt")

# 删除目录(包括所有内容)
shutil.rmtree("temp_folder", ignore_errors=True)

# 创建 zip 压缩包
shutil.make_archive("backup", "zip", "data")

# 获取磁盘空间
total, used, free = shutil.disk_usage("/")
print(f"可用空间: {free // 1024**3} GB")

glob----文件通配符匹配

函数说明示例
glob.glob(pattern) 返回匹配的文件列表 glob.glob("*.py")
glob.iglob(pattern) 返回迭代器(节省内存) for f in glob.iglob("*.txt"):
import glob

# 查找所有 Python 文件
py_files = glob.glob("*.py")
print(py_files)

# 递归查找
all_files = glob.glob("**/*.txt", recursive=True)

# 查找特定模式
log_files = glob.glob("logs/*.log")

datetime——日期时间处理

类/函数说明示例
datetime.now() 获取当前时间 datetime.now()
datetime(year, month, day) 创建日期对象 datetime(2024, 1, 15)
date.today() 获取当前日期 date.today()
date(year, month, day) 创建日期对象 date(2024, 1, 15)
timedelta(days, hours, ...) 时间差 timedelta(days=7)
strftime(format) 格式化日期为字符串 now.strftime("%Y-%m-%d")
strptime(date_str, format) 将字符串解析为日期 datetime.strptime("2024-01-15", "%Y-%m-%d")
from datetime import datetime, date, timedelta

# 当前时间
now = datetime.now()
print(now)                      # 2024-01-15 14:30:25.123456
print(now.strftime("%Y年%m月%d日 %H:%M:%S"))  # 2024年01月15日 14:30:25

# 日期运算
today = date.today()
tomorrow = today + timedelta(days=1)
last_week = today - timedelta(days=7)
print(f"明天: {tomorrow}")

# 字符串解析
date_str = "2024-12-25 10:30:00"
parsed = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
print(parsed)

# 格式化格式速查
# %Y: 2024  %m: 01  %d: 15  %H: 14  %M: 30  %S: 25
# %A: 星期一  %B: 一月

time——时间相关操作

函数说明示例
time.time() 获取时间戳(秒) time.time()1705317000.123
time.sleep(seconds) 程序暂停指定秒数 time.sleep(1)
time.localtime() 时间戳转本地时间元组 time.localtime()
time.strftime(format) 格式化时间 time.strftime("%Y-%m-%d")
time.perf_counter() 高精度计时(性能测试) start = time.perf_counter()
import time

# 计时器
start = time.perf_counter()
# 执行一些操作
time.sleep(0.5)
elapsed = time.perf_counter() - start
print(f"耗时: {elapsed:.4f} 秒")

# 时间戳
timestamp = time.time()
print(f"时间戳: {timestamp}")

# 暂停
print("开始...")
time.sleep(2)
print("继续...")

math——数学函数

函数/常量说明示例
math.pi 圆周率 π math.pi3.141592...
math.e 自然常数 e math.e2.718281...
math.sqrt(x) 平方根 math.sqrt(16)4.0
math.pow(x, y) 幂运算 math.pow(2, 3)8.0
math.ceil(x) 向上取整 math.ceil(3.2)4
math.floor(x) 向下取整 math.floor(3.8)3
math.round(x) 四舍五入 round(3.5)4
math.fabs(x) 绝对值 math.fabs(-5)5.0
math.sin(x) / math.cos(x) 三角函数(弧度) math.sin(math.pi/2)1.0
math.radians(deg) 角度转弧度 math.radians(180)3.14159
math.degrees(rad) 弧度转角度 math.degrees(math.pi)180.0
math.log(x, base) 对数 math.log(100, 10)2.0
math.comb(n, k) 组合数 C(n,k) math.comb(5, 2)10
math.perm(n, k) 排列数 P(n,k) math.perm(5, 2)20
math.factorial(n) 阶乘 math.factorial(5)120
import math

print(math.pi)                 # 3.141592653589793
print(math.sqrt(64))           # 8.0
print(math.ceil(3.2))          # 4
print(math.floor(3.8))         # 3
print(math.comb(5, 2))         # 10(从5个中选2个)
print(math.factorial(5))       # 120

random——随机数生成

函数说明示例
random.random() 生成 [0, 1) 间的浮点数 random.random()0.374
random.randint(a, b) 生成 [a, b] 间的整数 random.randint(1, 10)
random.randrange(start, stop, step) 生成指定步长的整数 random.randrange(0, 10, 2)
random.choice(seq) 从序列中随机选一个元素 random.choice(["a","b","c"])
random.choices(seq, k=n) 从序列中随机选 n 个元素(可重复) random.choices(["a","b"], k=3)
random.sample(seq, k) 从序列中随机选 k 个元素(不重复) random.sample(range(10), 3)
random.shuffle(lst) 打乱列表顺序 random.shuffle(cards)
random.seed(n) 设置随机种子(可复现) random.seed(42)
random.uniform(a, b) 生成 [a, b] 间的浮点数 random.uniform(1.0, 5.0)
import random

# 设置随机种子(结果可复现)
random.seed(42)

print(random.random())           # 0.6394267984578837
print(random.randint(1, 100))    # 82
print(random.choice(["苹果", "香蕉", "橙子"]))  # 橙子

# 洗牌
cards = ["A", "2", "3", "4", "5"]
random.shuffle(cards)
print(cards)  # ['3', 'A', '5', '4', '2']

# 随机抽样(不重复)
lottery = random.sample(range(1, 50), 6)
print(lottery)  # [12, 3, 45, 22, 9, 38]

statistics——统计函数

函数说明示例
statistics.mean(data) 算术平均数 mean([1,2,3,4,5])3.0
statistics.median(data) 中位数 median([1,2,3,4,5])3
statistics.mode(data) 众数(出现最多的值) mode([1,1,2,2,2,3])2
statistics.stdev(data) 样本标准差 stdev([1,2,3,4,5])1.58
statistics.variance(data) 样本方差 variance([1,2,3,4,5])2.5
statistics.quantiles(data, n) 分位数 quantiles([1,2,3,4,5], n=4)
import statistics

scores = [85, 92, 78, 90, 88, 92, 76]

print(f"平均分: {statistics.mean(scores):.2f}")     # 85.86
print(f"中位数: {statistics.median(scores)}")       # 88
print(f"众数: {statistics.mode(scores)}")           # 92
print(f"标准差: {statistics.stdev(scores):.2f}")    # 6.23

re——正则表达式

函数说明示例
re.match(pattern, str) 从开头匹配 re.match(r"\d+", "123abc")
re.search(pattern, str) 搜索第一个匹配 re.search(r"\d+", "abc123def")
re.findall(pattern, str) 查找所有匹配 re.findall(r"\d+", "a1b2c3")['1','2','3']
re.finditer(pattern, str) 查找所有匹配(迭代器) re.finditer(r"\d+", text)
re.sub(pattern, repl, str) 替换匹配内容 re.sub(r"\d+", "X", "a1b2")'aXbX'
re.split(pattern, str) 按正则分割 re.split(r"[,\s]+", "a,b c")['a','b','c']
re.compile(pattern) 编译正则(提高性能) pattern = re.compile(r"\d+")
import re

text = "我的电话是 138-1234-5678,邮箱是 abc@example.com"

# 查找所有数字
numbers = re.findall(r"\d+", text)
print(numbers)  # ['138', '1234', '5678']

# 搜索邮箱
email = re.search(r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}", text)
if email:
    print(email.group())  # abc@example.com

# 替换
masked = re.sub(r"\d", "X", text)
print(masked)

# 编译正则(性能更好,尤其循环中)
pattern = re.compile(r"\d{3}-\d{4}-\d{4}")
phone = pattern.search("138-1234-5678")
print(phone.group())  # 138-1234-5678

collections——高级容器类型

类型说明示例
defaultdict(factory) 带默认值的字典 d = defaultdict(int)
Counter(iterable) 计数器(统计频率) Counter("hello"){'l':2, 'h':1, ...}
OrderedDict() 有序字典(Python 3.7+ 内置 dict 已有序) OrderedDict([('a',1), ('b',2)])
deque(iterable) 双端队列(高效两端操作) dq = deque([1,2,3])
namedtuple(name, fields) 具名元组 Point = namedtuple('Point', ['x', 'y'])
from collections import defaultdict, Counter, deque, namedtuple

# defaultdict
d = defaultdict(int)
d["a"] += 1
d["b"] += 2
print(d)  # {'a': 1, 'b': 2}

# Counter
words = "hello world hello python"
counter = Counter(words.split())
print(counter)  # {'hello': 2, 'world': 1, 'python': 1}
print(counter.most_common(1))  # [('hello', 2)]

# deque(两端操作高效)
dq = deque([1, 2, 3])
dq.appendleft(0)
dq.append(4)
print(dq)  # deque([0, 1, 2, 3, 4])
dq.popleft()
dq.pop()

# namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(p.x, p.y)  # 10 20
print(p[0], p[1])  # 10 20(支持索引)

itertools——迭代器工具

函数说明示例
itertools.count(start, step) 无限计数器 for i in count(1, 2):
itertools.cycle(iterable) 无限循环迭代 for x in cycle([1,2,3]):
itertools.repeat(value, n) 重复生成值 list(repeat(5, 3))[5,5,5]
itertools.chain(*iterables) 拼接多个迭代器 chain([1,2], [3,4])
itertools.product(*iterables) 笛卡尔积 product([1,2], ['a','b'])
itertools.permutations(iterable, r) 排列 permutations([1,2,3], 2)
itertools.combinations(iterable, r) 组合 combinations([1,2,3], 2)
itertools.groupby(iterable, key) 按 key 分组 groupby(data, key=lambda x: x[0])
from itertools import chain, product, combinations, permutations

# 拼接
print(list(chain([1, 2], [3, 4], [5, 6])))  # [1, 2, 3, 4, 5, 6]

# 笛卡尔积
colors = ["红", "蓝"]
sizes = ["S", "M", "L"]
for item in product(colors, sizes):
    print(item)  # ('红','S'), ('红','M'), ...

# 组合(从 3 个中选 2 个)
print(list(combinations([1, 2, 3], 2)))  # [(1,2), (1,3), (2,3)]

# 排列(从 3 个中选 2 个,有序)
print(list(permutations([1, 2, 3], 2)))  # [(1,2), (1,3), (2,1), (2,3), (3,1), (3,2)]

urllib——URL 处理(HTTP 请求)

💡 建议:实际项目中推荐使用 requests 模块(第三方,更易用)。

函数/类说明示例
urllib.request.urlopen(url) 发送 HTTP 请求 response = urlopen("https://api.example.com")
urllib.parse.urlencode(params) 编码 URL 参数 urlencode({"q": "python"})
import urllib.request
import urllib.parse

# 发送 GET 请求
response = urllib.request.urlopen("https://httpbin.org/get")
data = response.read().decode("utf-8")
print(data)

# POST 请求
params = urllib.parse.urlencode({"name": "张三", "age": 25})
req = urllib.request.Request(
    "https://httpbin.org/post",
    data=params.encode("utf-8"),
    method="POST"
)
response = urllib.request.urlopen(req)
print(response.read().decode("utf-8"))

logging——日志记录

函数说明示例
logging.debug(msg) 调试信息 logging.debug("变量值: 10")
logging.info(msg) 一般信息 logging.info("程序启动")
logging.warning(msg) 警告信息 logging.warning("内存不足")
logging.error(msg) 错误信息 logging.error("文件未找到")
logging.critical(msg) 严重错误 logging.critical("系统崩溃")
logging.basicConfig() 配置日志格式 logging.basicConfig(level=logging.INFO)
import logging

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s",
    datefmt="%Y-%m-%d %H:%M:%S",
    filename="app.log",
    filemode="a"
)

# 使用日志
logging.info("程序启动")
try:
    result = 10 / 0
except ZeroDivisionError as e:
    logging.error(f"发生错误: {e}")

hashlib——哈希算法

函数/类说明示例
hashlib.md5() MD5 哈希 hashlib.md5(b"hello").hexdigest()
hashlib.sha1() SHA1 哈希 hashlib.sha1(b"hello").hexdigest()
hashlib.sha256() SHA256 哈希 hashlib.sha256(b"hello").hexdigest()
hashlib.sha512() SHA512 哈希 hashlib.sha512(b"hello").hexdigest()
import hashlib

# 计算文件 MD5
def get_file_md5(filename):
    md5 = hashlib.md5()
    with open(filename, "rb") as f:
        for chunk in iter(lambda: f.read(4096), b""):
            md5.update(chunk)
    return md5.hexdigest()

# 密码哈希
password = "my_password"
hashed = hashlib.sha256(password.encode()).hexdigest()
print(hashed)

copy——对象拷贝

函数说明示例
copy.copy(obj) 浅拷贝 copy.copy(list1)
copy.deepcopy(obj) 深拷贝 copy.deepcopy(list1)
import copy

lst1 = [[1, 2], [3, 4]]
lst2 = copy.copy(lst1)      # 浅拷贝
lst3 = copy.deepcopy(lst1)  # 深拷贝

lst1[0][0] = 999
print(lst2)  # [[999, 2], [3, 4]](浅拷贝受影响)
print(lst3)  # [[1, 2], [3, 4]](深拷贝不受影响)

typing——类型注解

from typing import List, Dict, Optional, Tuple, Union, Any

def process_data(data: List[int]) -> Dict[str, int]:
    return {"sum": sum(data)}

def get_user(name: str, age: Optional[int] = None) -> Dict[str, Union[str, int]]:
    user = {"name": name}
    if age is not None:
        user["age"] = age
    return user

五、Python面向对象

一、类与对象基础

1.1 类的定义与实例化

class Student:
    """学生类"""
    # 类属性(所有实例共享)
    school = "北京大学"
    
    # 构造方法:初始化实例
    def __init__(self, name, age, score):
        # 实例属性
        self.name = name
        self.age = age
        self.score = score
    
    # 实例方法
    def study(self, hours):
        print(f"{self.name} 学习了 {hours} 小时")

# 创建实例
s1 = Student("张三", 20, 85)
s2 = Student("李四", 22, 92)

# 访问属性
print(s1.name)          # 张三
print(s1.school)        # 北京大学(类属性)

# 调用方法
s1.study(3)             # 张三 学习了 3 小时

self关键字 

概念说明
self 代表实例本身,是实例方法的第一个参数
作用 在类内部访问实例的属性和方法
命名 约定俗成叫 self,可以改名但不建议

class Person: def __init__(self, name): self.name = name # self 绑定实例属性 def introduce(self): print(f"我是 {self.name}") # 通过 self 访问实例属性 # 调用时 Python 自动传入 self p = Person("张三") p.introduce() # 等价于 Person.introduce(p)

1.2 类属性与实例属性的区别

属性类型定义位置访问方式存储位置
类属性 类内部,方法外部 类名.属性实例.属性 类本身
实例属性 __init__ 中用 self.属性 实例.属性 每个实例独立
class Car:
    # 类属性(所有实例共享)
    wheels = 4
    
    def __init__(self, brand, color):
        # 实例属性(每个实例独立)
        self.brand = brand
        self.color = color

c1 = Car("特斯拉", "红色")
c2 = Car("宝马", "蓝色")

print(c1.wheels)      # 4(类属性)
print(Car.wheels)     # 4(类属性)

c1.wheels = 5         # 创建实例属性,不影响类属性
print(c1.wheels)      # 5
print(Car.wheels)     # 4

1.3 实例方法、类方法、静态方法区别

方法类型第一个参数装饰器访问权限适用场景
实例方法 self(实例) 可访问实例和类属性 需要操作实例数据
类方法 cls(类) @classmethod 只能访问类属性 操作类级别数据
静态方法 无(不自动传入) @staticmethod 不能访问实例/类属性 工具函数,与类相关
class Example:
    class_attr = "类属性"
    
    def __init__(self, value):
        self.value = value
    
    # 实例方法
    def instance_method(self):
        return f"实例方法: {self.value}, {self.class_attr}"
    
    # 类方法
    @classmethod
    def class_method(cls):
        return f"类方法: {cls.class_attr}"
    
    # 静态方法
    @staticmethod
    def static_method():
        return "静态方法: 无法访问实例或类属性"

e = Example("hello")
print(e.instance_method())      # 实例方法: hello, 类属性
print(Example.class_method())   # 类方法: 类属性
print(Example.static_method())  # 静态方法: 无法访问实例或类属性

实例方法(Instance Method)

class Student:
    school = "北京大学"
    
    def __init__(self, name, score):
        self.name = name
        self.score = score
    
    # 实例方法
    def get_score(self):
        return self.score
    
    def update_score(self, new_score):
        self.score = new_score
    
    def introduce(self):
        print(f"我叫 {self.name},来自 {self.school}")

s = Student("张三", 85)
print(s.get_score())    # 85
s.update_score(90)
print(s.get_score())    # 90
s.introduce()           # 我叫 张三,来自 北京大学

类方法

第一个参数是 cls,表示类本身。使用 @classmethod 装饰器。

  • 工厂方法(创建实例)

  • 操作类属性

  • 替代构造函数

class Student:
    school = "北京大学"
    count = 0
    
    def __init__(self, name):
        self.name = name
        Student.count += 1
    
    # 类方法
    @classmethod
    def get_school(cls):
        return cls.school
    
    @classmethod
    def set_school(cls, new_school):
        cls.school = new_school
    
    @classmethod
    def get_count(cls):
        return cls.count

# 通过类调用
print(Student.get_school())     # 北京大学
Student.set_school("清华大学")
print(Student.get_school())     # 清华大学

# 通过实例调用(也能工作,但建议用类)
s = Student("张三")
print(s.get_school())           # 清华大学

静态方法(Static Method)

使用 @staticmethod 装饰器,不自动传入 selfcls

  • 工具函数

  • 与类逻辑相关但不需要访问实例/类数据的函数

class MathUtils:
    # 静态方法:与类相关但不需要实例或类数据
    @staticmethod
    def add(a, b):
        return a + b
    
    @staticmethod
    def is_even(n):
        return n % 2 == 0
    
    @staticmethod
    def factorial(n):
        if n <= 1:
            return 1
        return n * MathUtils.factorial(n - 1)

# 通过类调用
print(MathUtils.add(3, 5))          # 8
print(MathUtils.is_even(10))        # True
print(MathUtils.factorial(5))       # 120

# 通过实例调用(也能工作)
math = MathUtils()
print(math.add(2, 3))               # 5

1.4 魔法方法

官方文档:https://docs.python.org/zh-cn/3/reference/datamodel.html#special-method-names

魔法方法是以双下划线开头和结尾的特殊方法(如 __init__),在特定操作时自动调用。(相当于在Java中方法的重写)

 
特征说明
命名格式 __method__(双下划线)
调用方式 自动调用,通常不直接调用
作用 实现对象的各种行为(初始化、运算、比较等)

对象的初始化与销毁

方法触发时机示例
__init__(self, ...) 实例化时 obj = MyClass()
__new__(cls, ...) 创建实例时(先于 __init__ 单例模式
__del__(self) 实例被销毁时 del obj
class Person:
    def __new__(cls, name):
        print(f"1. __new__ 被调用,创建 {name}")
        return super().__new__(cls)
    
    def __init__(self, name):
        print(f"2. __init__ 被调用,初始化 {name}")
        self.name = name
    
    def __del__(self):
        print(f"3. __del__ 被调用,{self.name} 被销毁")

p = Person("张三")
del p
# 输出:
# 1. __new__ 被调用,创建 张三
# 2. __init__ 被调用,初始化 张三
# 3. __del__ 被调用,张三 被销毁

比较运算符

方法运算符用途
__eq__(self, other) == 等于
__ne__(self, other) != 不等于
__lt__(self, other) < 小于
__le__(self, other) <= 小于等于
__gt__(self, other) > 大于
__ge__(self, other) >= 大于等于
class Score:
    def __init__(self, value):
        self.value = value
    
    def __eq__(self, other):
        return self.value == other.value
    
    def __lt__(self, other):
        return self.value < other.value
    
    def __gt__(self, other):
        return self.value > other.value
    
    def __repr__(self):
        return f"Score({self.value})"

s1 = Score(85)
s2 = Score(90)
s3 = Score(85)

print(s1 == s2)     # False
print(s1 == s3)     # True
print(s1 < s2)      # True
print(s2 > s1)      # True

  

  

 

posted @ 2026-07-19 21:04  Java小白的搬砖路  阅读(9)  评论(0)    收藏  举报