Python 学习笔记
一、Python 简介
1.1 什么是 Python?
Python 是一种高级、通用、解释型 的编程语言,由 Guido van Rossum 于 1991 年创建。它以简洁、易读的语法著称,是目前全球最流行的编程语言之一。
1.2 Python 的特点
语法简洁 :接近自然语言,代码可读性极高
跨平台 :支持 Windows、macOS、Linux 等操作系统
解释型语言 :无需编译,逐行解释执行
动态类型 :变量类型在运行时确定,无需显式声明
丰富的生态 :拥有庞大的标准库和第三方库
1.3 主要应用领域
领域
代表框架/库
Web 开发
Django、Flask、FastAPI
数据科学
NumPy、Pandas、Matplotlib
机器学习
TensorFlow、PyTorch、scikit-learn
自动化脚本
os、shutil、subprocess
网络爬虫
Requests、BeautifulSoup、Scrapy
嵌入式系统
MicroPython
1.4 Python 2 与 Python 3
Python 2 已于 2020 年正式停止维护,当前所有新项目均应使用 Python 3 。两者在语法上存在不兼容之处,本笔记所有内容均基于 Python 3.10+ 。
二、环境配置
2.1 安装 Python
Windows
访问 https://www.python.org/downloads/ 下载安装包
安装时勾选 Add Python to PATH (必须勾选,否则命令行无法识别 python 命令)
验证安装:
macOS
brew install python3 python3 --version
Linux(Ubuntu/Debian)
sudo apt updatesudo apt install python3 python3-pip
2.2 虚拟环境
虚拟环境是 Python 项目的隔离空间,用于避免不同项目之间的依赖冲突。每个项目都应该使用独立的虚拟环境。
python -m venv myenv myenv\Scripts\activate source myenv/bin/activatedeactivate
激活后,命令行提示符前会出现 (myenv) 字样,表示当前处于虚拟环境中。此时安装的所有包只作用于该环境,不影响系统全局。
2.3 包管理(pip)
pip install requests pip install requests==2.28.0 pip install --upgrade requests pip uninstall requests pip list pip freeze > requirements.txt pip install -r requirements.txt
requirements.txt 是协作开发中共享依赖信息的标准方式,提交项目时应一并上传。
三、基础语法
3.1 注释
""" 这是多行注释(文档字符串) 通常用于函数、类、模块的说明文档 """ ''' 也可以用单引号的三引号 '''
3.2 代码结构规范
Python 使用缩进 来表示代码块,而不是花括号。缩进不正确会直接导致程序报错。
if True : print ("正确" ) if True : print ("这行是4空格" ) print ("这行是6空格" )
3.3 导入模块
import osimport mathfrom datetime import datetimefrom os.path import join, existsimport numpy as npimport pandas as pdif __name__ == '__main__' : main()
if __name__ == '__main__' 的作用:当该文件被直接运行时执行其中的代码,当被其他文件导入时不执行。这是 Python 模块化开发的基本规范。
3.4 变量与命名规范
name = "张三" age = 18 score = 95.5 is_student = True x = y = z = 0 a, b, c = 1 , 2 , 3 user_name = "张三" MAX_SIZE = 100 class UserInfo : pass
3.5 基本输入输出
print ("Hello, World!" )print ("姓名:" , "张三" , "年龄:" , 18 ) print ("第一行" , end="" ) print ("同一行" )name = "张三" age = 18 print (f"我叫 {name} ,今年 {age} 岁" )print (f"π 保留两位小数:{3.14159 :.2 f} " )print (f"数字补零:{age:05d} " ) name = input ("请输入你的名字:" ) age = int (input ("请输入你的年龄:" ))
四、数据类型
4.1 基本数据类型概览
Python 共有以下基本数据类型:
类型
关键字
示例
是否可变
整数
int
42、-10
否
浮点数
float
3.14、-2.5
否
复数
complex
3+4j
否
布尔值
bool
True、False
否
字符串
str
"hello"
否
空值
NoneType
None
否
4.2 整数(int)
x = 10 y = -5 large_num = 1_000_000 binary = 0b1010 octal = 0o12 hexadecimal = 0xFF big = 10 ** 100
4.3 浮点数(float)
a = 3.14 b = -2.5 c = 2.0 scientific = 1.23e-4 print (0.1 + 0.2 ) print (0.1 + 0.2 == 0.3 ) print (round (0.1 + 0.2 , 1 ) == 0.3 ) from decimal import Decimalprint (Decimal("0.1" ) + Decimal("0.2" ))
浮点数精度问题是所有编程语言的通病,根源在于计算机用二进制表示小数时存在精度损失。涉及金融计算时应使用 decimal 模块。
4.4 布尔值(bool)
is_valid = True is_empty = False print (True + True ) print (True * 5 ) bool (False ) bool (0 ) bool (0.0 ) bool (None ) bool ("" ) bool ([]) bool ({}) bool (()) bool (set ()) bool (1 ) bool (-1 ) bool ("0" ) bool ([0 ])
4.5 空值(None)
result = None def do_something (): print ("执行" ) print (do_something()) data = None if some_condition: data = fetch_data() if result is None : print ("没有结果" ) if result is not None : print ("有结果" )
4.6 类型检查与转换
print (type (42 )) print (type (3.14 )) print (type ("hello" )) print (type (True )) print (type (None )) print (isinstance (42 , int )) print (isinstance (True , int )) print (isinstance (3.14 , (int , float ))) int ("123" ) int (3.9 ) float ("3.14" ) str (100 ) bool (0 ) list ("abc" ) tuple ([1 , 2 , 3 ]) int ("abc" )
4.7 可变与不可变类型
这是 Python 中一个非常重要的概念,直接影响函数传参、赋值等行为。
x = 10 print (id (x)) x = 20 print (id (x)) s = "hello" s = "Hello" lst = [1 , 2 , 3 ] print (id (lst)) lst.append(4 ) print (id (lst)) def modify (data ): data.append(99 ) my_list = [1 , 2 , 3 ] modify(my_list) print (my_list) def modify_int (num ): num = 100 my_num = 10 modify_int(my_num) print (my_num)
五、字符串
5.1 字符串创建
s1 = '单引号' s2 = "双引号" s3 = """多行 字符串""" path = r"C:\Users\Name\Documents" pattern = r"\d+\.\d+" b = b"hello"
5.2 字符串索引与切片
text = "Hello, Python!" print (text[0 ]) print (text[-1 ]) print (text[7 ]) print (text[0 :5 ]) print (text[7 :]) print (text[:5 ]) print (text[::2 ]) print (text[::-1 ])
5.3 字符串常用方法
s = " Hello, World! " s.upper() s.lower() s.title() s.swapcase() s.strip() s.lstrip() s.rstrip() s.find("World" ) s.rfind("o" ) s.index("World" ) s.count("l" ) "123" .isdigit() "abc" .isalpha() "abc123" .isalnum() " " .isspace() "hello" .islower() "HELLO" .isupper() "Hello" .startswith("He" ) "Hello" .endswith("lo" ) s.replace("World" , "Python" ) "a,b,c" .split("," ) "a b c" .split() "-" .join(["a" , "b" , "c" ]) "5" .zfill(4 ) "hi" .center(10 , "*" ) "hi" .ljust(10 , "-" ) "hi" .rjust(10 , "-" )
5.4 字符串格式化
name = "张三" age = 18 score = 95.678 print (f"我叫{name} ,今年{age} 岁" )print (f"成绩:{score:.2 f} " ) print (f"年龄补零:{age:05d} " ) print (f"左对齐:{name:<10 } " ) print (f"右对齐:{name:>10 } " ) print (f"居中:{name:^10 } " ) print (f"表达式:{age * 2 } " ) print ("{}今年{}岁" .format (name, age))print ("{name}今年{age}岁" .format (name="李四" , age=20 ))print ("%s今年%d岁" % (name, age))
5.5 转义字符
print ("换行:第一行\n第二行" )print ("制表符:姓名\t年龄" )print ("反斜杠:C:\\Users\\Name" )print ("单引号:I\'m fine" )print ("双引号:He said \"Hello\"" )print ("\u4e2d\u6587" ) print ("\n" .join(["a" , "b" , "c" ]))
六、数字与数学运算
6.1 算术运算符
a, b = 10 , 3 print (a + b) print (a - b) print (a * b) print (a / b) print (a // b) print (a % b) print (a ** b) print (7 // 2 ) print (-7 // 2 ) print (7 % -2 ) print (divmod (10 , 3 ))
6.2 赋值运算符
x = 10 x += 5 x -= 3 x *= 2 x /= 4 x //= 2 x %= 2 x **= 3
6.3 比较与逻辑运算符
print (5 == 5 ) print (5 != 3 ) print (5 > 3 ) print (5 >= 5 ) x = 5 print (0 < x < 10 ) print (1 < 2 < 3 < 4 ) a = [1 , 2 , 3 ] b = [1 , 2 , 3 ] c = a print (a == b) print (a is b) print (a is c) result = None print (result is None ) print (result == None ) print (True and False ) print (True or False ) print (not True ) print (0 and 1 /0 ) print (1 or 1 /0 ) name = "" or "匿名用户"
6.4 math 模块
import mathprint (math.pi) print (math.e) print (math.inf) print (math.nan) print (abs (-5 )) print (round (3.14159 , 2 )) print (math.sqrt(16 )) print (math.ceil(3.2 )) print (math.floor(3.8 )) print (math.trunc(-3.8 )) print (round (0.5 )) print (round (1.5 )) print (round (2.5 )) print (math.pow (2 , 10 )) print (math.log(math.e)) print (math.log10(100 )) print (math.log2(8 )) print (max (1 , 5 , 3 )) print (min (1 , 5 , 3 )) print (sum ([1 , 2 , 3 , 4 ]))
6.5 进制转换
print (bin (10 )) print (oct (10 )) print (hex (255 )) print (bin (10 )[2 :]) print (format (10 , 'b' )) print (format (255 , 'x' )) print (format (255 , 'X' )) print (format (255 , '08b' )) print (int ("1010" , 2 )) print (int ("ff" , 16 )) print (int ("12" , 8 ))
七、流程控制
7.1 条件语句
score = 85 if score >= 90 : grade = "A" elif score >= 80 : grade = "B" elif score >= 70 : grade = "C" elif score >= 60 : grade = "D" else : grade = "F" print (grade) age = 20 status = "成年" if age >= 18 else "未成年" age = 25 has_license = True if age >= 18 : if has_license: print ("可以开车" ) else : print ("需要先考驾照" ) else : print ("年龄不够" ) command = "quit" match command: case "start" : print ("启动" ) case "stop" : print ("停止" ) case "quit" | "exit" : print ("退出" ) case _: print ("未知命令" )
7.2 for 循环
fruits = ["apple" , "banana" , "cherry" ] for fruit in fruits: print (fruit) for char in "Python" : print (char, end=" " ) for i in range (5 ): print (i) for i in range (2 , 8 ): print (i) for i in range (0 , 10 , 2 ): print (i) for i in range (10 , 0 , -1 ): print (i) for index, value in enumerate (fruits): print (f"第{index} 个:{value} " ) for index, value in enumerate (fruits, start=1 ): print (f"第{index} 个:{value} " ) names = ["张三" , "李四" , "王五" ] scores = [90 , 85 , 78 ] for name, score in zip (names, scores): print (f"{name} :{score} 分" ) person = {"name" : "张三" , "age" : 18 , "city" : "北京" } for key in person: print (key) for value in person.values(): print (value) for key, value in person.items(): print (f"{key} : {value} " ) for i in range (5 ): print (i) else : print ("循环正常结束" ) for num in range (2 , 20 ): for i in range (2 , int (num**0.5 ) + 1 ): if num % i == 0 : break else : print (f"{num} 是质数" )
7.3 while 循环
count = 0 while count < 5 : print (count) count += 1 while True : user_input = input ("输入 q 退出:" ) if user_input == 'q' : break print (f"你输入了:{user_input} " ) count = 0 while count < 5 : count += 1 else : print ("while 循环结束" )
7.4 循环控制语句
for i in range (10 ): if i == 5 : break print (i) for i in range (5 ): if i == 2 : continue print (i) for i in range (5 ): if i == 2 : pass else : print (i) found = False for i in range (5 ): for j in range (5 ): if i == 2 and j == 3 : found = True break if found: break print (f"找到了 i={i} , j={j} " )
7.5 推导式
推导式是 Python 中非常重要的语法特性,可以用简洁的方式创建列表、字典、集合。
squares = [x**2 for x in range (10 )] print (squares) even_squares = [x**2 for x in range (10 ) if x % 2 == 0 ] print (even_squares) matrix = [[1 , 2 , 3 ], [4 , 5 , 6 ], [7 , 8 , 9 ]] flat = [num for row in matrix for num in row] print (flat) squares_dict = {x: x**2 for x in range (5 )} print (squares_dict) original = {"a" : 1 , "b" : 2 , "c" : 3 } reversed_dict = {v: k for k, v in original.items()} print (reversed_dict) unique_chars = {char.lower() for char in "Hello World" if char != " " } print (unique_chars) gen = (x**2 for x in range (1000000 )) print (next (gen)) print (sum (x**2 for x in range (100 )))
八、函数
8.1 函数定义与调用
def greet (): """函数的文档字符串,描述函数的作用""" print ("Hello, World!" ) greet() def greet_person (name ): print (f"Hello, {name} !" ) greet_person("张三" ) def add (a, b ): return a + b result = add(3 , 5 ) print (result) def get_min_max (numbers ): return min (numbers), max (numbers) minimum, maximum = get_min_max([3 , 1 , 4 , 1 , 5 , 9 ]) print (f"最小值:{minimum} ,最大值:{maximum} " )def no_return (): print ("执行了" ) print (no_return())
8.2 函数参数
def power (base, exponent ): return base ** exponent print (power(2 , 3 )) print (power(exponent=3 , base=2 )) def greet (name, greeting="你好" ): print (f"{greeting} ,{name} !" ) greet("张三" ) greet("李四" , "早上好" ) def append_to (element, to=[] ): to.append(element) return to print (append_to(1 )) print (append_to(2 )) def append_to (element, to=None ): if to is None : to = [] to.append(element) return to def sum_all (*args ): print (type (args)) return sum (args) print (sum_all(1 , 2 , 3 )) print (sum_all(1 , 2 , 3 , 4 , 5 )) def print_info (**kwargs ): print (type (kwargs)) for key, value in kwargs.items(): print (f"{key} : {value} " ) print_info(name="张三" , age=18 , city="北京" ) def complex_function (a, b, *args, option=True , **kwargs ): print (f"a={a} , b={b} " ) print (f"args={args} " ) print (f"option={option} " ) print (f"kwargs={kwargs} " ) complex_function(1 , 2 , 3 , 4 , option=False , x=10 , y=20 ) def create_user (name, *, age, city ): return {"name" : name, "age" : age, "city" : city} create_user("张三" , age=18 , city="北京" )
8.3 作用域
x = "全局变量" def outer (): x = "外层变量" def inner (): x = "局部变量" print (x) inner() print (x) outer() print (x) count = 0 def increment (): global count count += 1 increment() increment() print (count) def make_counter (): count = 0 def increment (): nonlocal count count += 1 return count return increment counter = make_counter() print (counter()) print (counter()) print (counter())
8.4 闭包
闭包是指内层函数记住了其定义时所在的外层作用域的变量,即使外层函数已经执行完毕。
def make_multiplier (factor ): def multiplier (x ): return x * factor return multiplier double = make_multiplier(2 ) triple = make_multiplier(3 ) print (double(5 )) print (triple(5 )) def make_counter (start=0 ): count = start def increment (step=1 ): nonlocal count count += step return count def reset (): nonlocal count count = start def get (): return count return increment, reset, get inc, reset, get = make_counter(10 ) print (inc()) print (inc(5 )) print (get()) reset() print (get()) funcs = [] for i in range (3 ): funcs.append(lambda : i) print ([f() for f in funcs]) funcs = [] for i in range (3 ): funcs.append(lambda x=i: x) print ([f() for f in funcs])
8.5 装饰器
装饰器本质上是一个接受函数作为参数、返回新函数的高阶函数,用于在不修改原函数的前提下扩展其功能。
def timer (func ): import time def wrapper (*args, **kwargs ): start = time.time() result = func(*args, **kwargs) elapsed = time.time() - start print (f"{func.__name__} 耗时:{elapsed:.4 f} 秒" ) return result return wrapper @timer def slow_function (): import time time.sleep(1 ) slow_function() import functoolsdef timer (func ): @functools.wraps(func ) def wrapper (*args, **kwargs ): import time start = time.time() result = func(*args, **kwargs) elapsed = time.time() - start print (f"{func.__name__} 耗时:{elapsed:.4 f} 秒" ) return result return wrapper def repeat (n ): def decorator (func ): @functools.wraps(func ) def wrapper (*args, **kwargs ): for _ in range (n): result = func(*args, **kwargs) return result return wrapper return decorator @repeat(3 ) def say_hello (): print ("Hello!" ) say_hello() @timer @repeat(3 ) def greet (name ): print (f"Hello, {name} !" ) class Singleton : """单例模式装饰器""" def __init__ (self, cls ): self ._cls = cls self ._instance = None def __call__ (self, *args, **kwargs ): if self ._instance is None : self ._instance = self ._cls(*args, **kwargs) return self ._instance @Singleton class DatabaseConnection : def __init__ (self ): print ("创建数据库连接" ) db1 = DatabaseConnection() db2 = DatabaseConnection() print (db1 is db2)
8.6 Lambda 函数
square = lambda x: x ** 2 print (square(5 )) add = lambda a, b: a + b print (add(3 , 4 )) students = [ {"name" : "张三" , "score" : 85 }, {"name" : "李四" , "score" : 92 }, {"name" : "王五" , "score" : 78 }, ] sorted_students = sorted (students, key=lambda s: s["score" ]) sorted_students = sorted (students, key=lambda s: s["score" ], reverse=True ) sorted_students = sorted (students, key=lambda s: (-s["score" ], s["name" ])) numbers = [1 , 2 , 3 , 4 , 5 ] doubled = list (map (lambda x: x * 2 , numbers)) evens = list (filter (lambda x: x % 2 == 0 , numbers))
8.7 生成器
生成器是一种特殊的迭代器,使用 yield 关键字逐个产出值,不会一次性将所有数据加载到内存中。
def count_up_to (n ): count = 1 while count <= n: yield count count += 1 gen = count_up_to(5 ) print (next (gen)) print (next (gen)) print (next (gen)) for num in count_up_to(5 ): print (num) all_squares = [x**2 for x in range (1000000 )] gen_squares = (x**2 for x in range (1000000 )) print (next (gen_squares)) def read_large_file (filepath ): with open (filepath, "r" , encoding="utf-8" ) as f: for line in f: yield line.strip() for line in read_large_file("large_file.txt" ): process(line) def chain (*iterables ): for iterable in iterables: yield from iterable for item in chain([1 , 2 ], [3 , 4 ], [5 , 6 ]): print (item)
九、数据结构
9.1 列表(List)
empty = [] numbers = [1 , 2 , 3 , 4 , 5 ] mixed = [1 , "hello" , 3.14 , True , None ] nested = [[1 , 2 ], [3 , 4 ], [5 , 6 ]] list_from_range = list (range (5 )) list_from_str = list ("hello" ) lst = [10 , 20 , 30 , 40 , 50 ] print (lst[0 ]) print (lst[-1 ]) print (lst[1 :4 ]) print (lst[::-1 ]) lst.append(60 ) lst.insert(2 , 25 ) lst.extend([70 , 80 ]) lst.remove(25 ) popped = lst.pop() popped2 = lst.pop(0 ) del lst[1 :3 ] lst[0 ] = 99 lst[1 :3 ] = [100 , 200 ] lst = [3 , 1 , 4 , 1 , 5 , 9 , 2 , 6 ] print (lst.index(4 )) print (lst.count(1 )) print (1 in lst) lst.sort() lst.sort(reverse=True ) lst.sort(key=lambda x: abs (x)) new_lst = sorted (lst) lst.reverse() lst.clear() copy = lst.copy() import copydeep = copy.deepcopy(nested)
9.2 元组(Tuple)
元组与列表的最大区别是不可变 ,一旦创建就不能修改。
empty = () single = (1 ,) numbers = (1 , 2 , 3 , 4 , 5 ) mixed = (1 , "hello" , 3.14 ) t = 1 , 2 , 3 print (type (t)) point = (10 , 20 ) x, y = point print (x, y) first, *middle, last = (1 , 2 , 3 , 4 , 5 ) print (first) print (middle) print (last) a, b = 1 , 2 a, b = b, a print (a, b) def get_info (): return "张三" , 18 , "北京" name, age, city = get_info() d = {(0 , 0 ): "原点" , (1 , 0 ): "x轴上的点" } WEEKDAYS = ("周一" , "周二" , "周三" , "周四" , "周五" , "周六" , "周日" )
9.3 字典(Dictionary)
empty = {} person = {"name" : "张三" , "age" : 18 , "city" : "北京" } d = dict (name="李四" , age=20 ) print (person["name" ]) print (person.get("name" )) print (person.get("phone" )) print (person.get("phone" , "未知" )) person["email" ] = "test@test.com" person["age" ] = 19 person.update({"city" : "上海" , "job" : "工程师" }) del person["email" ] value = person.pop("city" ) value = person.pop("xx" , None ) key, val = person.popitem() for key in person: print (key) for value in person.values(): print (value) for key, value in person.items(): print (f"{key} : {value} " ) print ("name" in person) print ("张三" in person.values()) print (len (person)) keys = list (person.keys()) person.setdefault("score" , 0 ) d1 = {"a" : 1 , "b" : 2 } d2 = {"b" : 3 , "c" : 4 } merged = {**d1, **d2} merged = d1 | d2 squares = {x: x**2 for x in range (5 )} filtered = {k: v for k, v in person.items() if v is not None }
9.4 集合(Set)
empty = set () s = {1 , 2 , 3 , 4 , 5 } s_from_list = set ([1 , 2 , 2 , 3 , 3 ]) s.add(6 ) s.remove(1 ) s.discard(100 ) s.pop() s.clear() A = {1 , 2 , 3 , 4 , 5 } B = {4 , 5 , 6 , 7 , 8 } A | B A.union(B) A & B A.intersection(B) A - B A.difference(B) A ^ B A.symmetric_difference(B) {1 , 2 }.issubset({1 , 2 , 3 }) {1 , 2 , 3 }.issuperset({1 , 2 }) {1 , 2 }.isdisjoint({3 , 4 }) lst = [1 , 2 , 3 , 2 , 1 , 3 , 4 ] unique = list (set (lst)) valid_choices = {"yes" , "no" , "maybe" } user_input = "yes" if user_input in valid_choices: print ("有效输入" )
9.5 collections 模块
from collections import defaultdict, Counter, deque, OrderedDict, namedtupleword_count = defaultdict(int ) for word in "hello world hello" .split(): word_count[word] += 1 print (dict (word_count)) grouped = defaultdict(list ) for name, dept in [("张三" , "技术" ), ("李四" , "产品" ), ("王五" , "技术" )]: grouped[dept].append(name) print (dict (grouped)) words = ["apple" , "banana" , "apple" , "orange" , "banana" , "apple" ] c = Counter(words) print (c) print (c.most_common(2 )) print (c["apple" ]) print (c["grape" ]) c1 = Counter({"a" : 3 , "b" : 2 }) c2 = Counter({"a" : 1 , "c" : 4 }) print (c1 + c2) print (c1 - c2) dq = deque([1 , 2 , 3 ]) dq.append(4 ) dq.appendleft(0 ) dq.pop() dq.popleft() dq.rotate(1 ) recent = deque(maxlen=3 ) for i in range (5 ): recent.append(i) print (list (recent)) Point = namedtuple("Point" , ["x" , "y" ]) p = Point(10 , 20 ) print (p.x, p.y) print (p[0 ], p[1 ]) x, y = p Person = namedtuple("Person" , ["name" , "age" , "city" ]) alice = Person("Alice" , 25 , "北京" ) print (alice._asdict()) bob = alice._replace(name="Bob" )
十、面向对象编程
10.1 类与对象基础
class Dog : species = "Canis familiaris" count = 0 def __init__ (self, name, age ): self .name = name self .age = age Dog.count += 1 def bark (self ): return f"{self.name} 汪汪叫!" def get_info (self ): return f"{self.name} ,{self.age} 岁" @classmethod def get_count (cls ): return f"共有 {cls.count} 只狗" @staticmethod def is_adult (age ): return age >= 2 dog1 = Dog("小黑" , 3 ) dog2 = Dog("大白" , 1 ) print (dog1.name) print (dog1.bark()) print (Dog.species) print (dog1.species) print (Dog.get_count()) print (Dog.is_adult(3 )) dog1.color = "黑色" print (dog1.color) print (hasattr (dog2, "color" )) del dog1.color
10.2 继承
class Animal : def __init__ (self, name, sound ): self .name = name self .sound = sound def speak (self ): return f"{self.name} 说 {self.sound} " def move (self ): return f"{self.name} 在移动" def __str__ (self ): return f"Animal({self.name} )" class Dog (Animal ): def __init__ (self, name, breed ): super ().__init__(name, "汪汪" ) self .breed = breed def speak (self ): return f"{self.name} ({self.breed} )大声地叫:{self.sound} !" def fetch (self ): return f"{self.name} 去捡球了" class Cat (Animal ): def __init__ (self, name, is_indoor=True ): super ().__init__(name, "喵喵" ) self .is_indoor = is_indoor def speak (self ): prefix = "家猫" if self .is_indoor else "野猫" return f"{prefix} {self.name} :{self.sound} " dog = Dog("小黑" , "拉布拉多" ) cat = Cat("小花" ) print (dog.speak()) print (cat.speak()) print (dog.move()) print (isinstance (dog, Dog)) print (isinstance (dog, Animal)) print (issubclass (Dog, Animal)) class Flyable : def fly (self ): return "我会飞" class Swimmable : def swim (self ): return "我会游泳" class Duck (Animal, Flyable, Swimmable): def __init__ (self, name ): super ().__init__(name, "嘎嘎" ) duck = Duck("唐老鸭" ) print (duck.speak()) print (duck.fly()) print (duck.swim()) print (Duck.__mro__)
10.3 封装
class BankAccount : def __init__ (self, owner, balance=0 ): self .owner = owner self ._balance = balance self .__log = [] def deposit (self, amount ): if amount <= 0 : raise ValueError("存款金额必须大于0" ) self ._balance += amount self .__log.append(f"存入 {amount} " ) def withdraw (self, amount ): if amount <= 0 : raise ValueError("取款金额必须大于0" ) if amount > self ._balance: raise ValueError("余额不足" ) self ._balance -= amount self .__log.append(f"取出 {amount} " ) def get_balance (self ): return self ._balance def get_log (self ): return self .__log.copy() account = BankAccount("张三" , 1000 ) account.deposit(500 ) account.withdraw(200 ) print (account.get_balance()) print (account.get_log()) print (account._BankAccount__log)
10.4 属性(property)
class Person : def __init__ (self, name, age ): self ._name = name self ._age = age @property def name (self ): """姓名""" return self ._name @name.setter def name (self, value ): if not isinstance (value, str ) or not value.strip(): raise ValueError("姓名必须是非空字符串" ) self ._name = value.strip() @property def age (self ): """年龄""" return self ._age @age.setter def age (self, value ): if not isinstance (value, int ) or not (0 <= value <= 150 ): raise ValueError("年龄必须是0到150之间的整数" ) self ._age = value @property def is_adult (self ): """是否成年(只读属性,没有 setter)""" return self ._age >= 18 p = Person("张三" , 17 ) print (p.name) p.name = "李四" p.age = 25 print (p.is_adult)
10.5 特殊方法(魔法方法)
class Vector : def __init__ (self, x, y ): self .x = x self .y = y def __str__ (self ): """给用户看的字符串,print() 调用""" return f"Vector({self.x} , {self.y} )" def __repr__ (self ): """给开发者看的字符串,调试时使用""" return f"Vector(x={self.x} , y={self.y} )" def __add__ (self, other ): return Vector(self .x + other.x, self .y + other.y) def __sub__ (self, other ): return Vector(self .x - other.x, self .y - other.y) def __mul__ (self, scalar ): return Vector(self .x * scalar, self .y * scalar) def __rmul__ (self, scalar ): """支持 scalar * vector 的写法""" return self .__mul__(scalar) def __neg__ (self ): """取反:-vector""" return Vector(-self .x, -self .y) def __eq__ (self, other ): return self .x == other.x and self .y == other.y def __abs__ (self ): """abs() 函数支持""" import math return math.sqrt(self .x**2 + self .y**2 ) def __len__ (self ): return 2 def __getitem__ (self, index ): if index == 0 : return self .x elif index == 1 : return self .y raise IndexError(f"Vector 索引超出范围:{index} " ) def __iter__ (self ): yield self .x yield self .y def __contains__ (self, item ): return item in (self .x, self .y) def __enter__ (self ): print ("进入上下文" ) return self def __exit__ (self, exc_type, exc_val, exc_tb ): print ("退出上下文" ) return False v1 = Vector(3 , 4 ) v2 = Vector(1 , 2 ) print (v1) print (v1 + v2) print (v1 * 2 ) print (2 * v1) print (abs (v1)) print (v1[0 ]) print (3 in v1) print (list (v1)) with v1 as v: print (v)
10.6 抽象基类
from abc import ABC, abstractmethodclass Shape (ABC ): """抽象基类:不能直接实例化,强制子类实现指定方法""" @abstractmethod def area (self ): """计算面积""" pass @abstractmethod def perimeter (self ): """计算周长""" pass def describe (self ): return (f"面积:{self.area():.2 f} ," f"周长:{self.perimeter():.2 f} " ) class Rectangle (Shape ): def __init__ (self, width, height ): self .width = width self .height = height def area (self ): return self .width * self .height def perimeter (self ): return 2 * (self .width + self .height) class Circle (Shape ): def __init__ (self, radius ): self .radius = radius def area (self ): import math return math.pi * self .radius ** 2 def perimeter (self ): import math return 2 * math.pi * self .radius rect = Rectangle(3 , 4 ) circle = Circle(5 ) print (rect.describe()) print (circle.describe()) shapes = [Rectangle(3 , 4 ), Circle(5 ), Rectangle(6 , 2 )] total_area = sum (shape.area() for shape in shapes) print (f"总面积:{total_area:.2 f} " )
十一、异常处理
11.1 异常的概念
异常是程序运行时发生的错误。Python 中所有异常都是类,都继承自 BaseException。程序发生异常时,如果没有处理,程序会立即终止并打印错误信息。
11.2 基本异常处理
try : result = 10 / 0 except ZeroDivisionError: print ("不能除以零" ) try : result = int ("abc" ) except ValueError as e: print (f"发生错误:{e} " ) print (f"错误类型:{type (e).__name__} " ) try : num = int (input ("输入数字:" )) result = 10 / num except ValueError: print ("输入的不是有效数字" ) except ZeroDivisionError: print ("不能除以零" ) except Exception as e: print (f"发生未知错误:{e} " ) try : pass except (ValueError, TypeError) as e: print (f"值或类型错误:{e} " ) try : result = 10 / 2 except ZeroDivisionError: print ("除零错误" ) else : print (f"计算成功,结果是:{result} " ) try : f = open ("data.txt" , "r" ) content = f.read() except FileNotFoundError: print ("文件不存在" ) finally : print ("执行完毕" )
11.3 主动抛出异常
def validate_age (age ): if not isinstance (age, int ): raise TypeError(f"年龄必须是整数,收到了 {type (age).__name__} " ) if age < 0 or age > 150 : raise ValueError(f"年龄必须在 0 到 150 之间,收到了 {age} " ) return True try : validate_age(-5 ) except ValueError as e: print (f"验证失败:{e} " ) try : result = int ("abc" ) except ValueError: print ("记录日志:发生了 ValueError" ) raise try : int ("abc" ) except ValueError as e: raise RuntimeError("数据处理失败" ) from e
11.4 自定义异常
class AppError (Exception ): """应用的基础异常类""" pass class ValidationError (AppError ): """数据验证异常""" def __init__ (self, field, message ): self .field = field self .message = message super ().__init__(f"字段 '{field} ' 验证失败:{message} " ) class NetworkError (AppError ): """网络请求异常""" def __init__ (self, url, status_code ): self .url = url self .status_code = status_code super ().__init__(f"请求 {url} 失败,状态码:{status_code} " ) def validate_user (data ): if not data.get("name" ): raise ValidationError("name" , "姓名不能为空" ) if not isinstance (data.get("age" ), int ): raise ValidationError("age" , "年龄必须是整数" ) if data["age" ] < 0 : raise ValidationError("age" , "年龄不能为负数" ) try : validate_user({"name" : "" , "age" : 18 }) except ValidationError as e: print (f"验证错误:{e} " ) print (f"问题字段:{e.field} " ) except AppError as e: print (f"应用错误:{e} " )
11.5 常见内置异常
"hello" + 5 int ("abc" ) [1 , 2 , 3 ][10 ] {"a" : 1 }["b" ] "hello" .non_exist() print (undefined_var) open ("no_such_file.txt" ) 10 / 0 def f (): return f()f() import mathmath.exp(1000 ) it = iter ([1 ]) next (it) next (it)
11.6 上下文管理器
with open ("example.txt" , "w" , encoding="utf-8" ) as f: f.write("第一行\n" ) f.write("第二行\n" ) with open ("input.txt" , "r" ) as fin, open ("output.txt" , "w" ) as fout: fout.write(fin.read()) class Timer : def __init__ (self, name ): self .name = name def __enter__ (self ): import time self .start = time.time() print (f"开始计时:{self.name} " ) return self def __exit__ (self, exc_type, exc_val, exc_tb ): import time elapsed = time.time() - self .start print (f"结束计时:{self.name} ,耗时 {elapsed:.4 f} 秒" ) return False with Timer("数据处理" ) as t: import time time.sleep(0.5 ) from contextlib import contextmanager@contextmanager def timer (name ): import time start = time.time() print (f"开始:{name} " ) try : yield finally : elapsed = time.time() - start print (f"结束:{name} ,耗时 {elapsed:.4 f} 秒" ) with timer("任务" ): import time time.sleep(0.5 )
十二、文件操作
12.1 文件读写基础
with open ("example.txt" , "w" , encoding="utf-8" ) as f: f.write("第一行\n" ) f.write("第二行\n" ) f.writelines(["第三行\n" , "第四行\n" ]) with open ("example.txt" , "r" , encoding="utf-8" ) as f: content = f.read() print (content) with open ("example.txt" , "r" , encoding="utf-8" ) as f: first_line = f.readline() print (first_line) with open ("example.txt" , "r" , encoding="utf-8" ) as f: lines = f.readlines() print (lines) with open ("example.txt" , "r" , encoding="utf-8" ) as f: for line in f: print (line.strip()) with open ("example.txt" , "a" , encoding="utf-8" ) as f: f.write("第五行\n" )
12.2 文件与路径操作
import osfrom pathlib import Path p = Path("data/example.txt" ) print (p.name) print (p.stem) print (p.suffix) print (p.parent) print (p.absolute()) base = Path("data" ) full = base / "subdir" / "file.txt" p.exists() p.is_file() p.is_dir() Path("new_dir" ).mkdir(parents=True , exist_ok=True ) p.unlink() Path("empty_dir" ).rmdir() for item in Path("." ).iterdir(): print (item) for py_file in Path("." ).glob("*.py" ): print (py_file) for py_file in Path("." ).rglob("*.py" ): print (py_file) p = Path("example.txt" ) p.write_text("内容" , encoding="utf-8" ) content = p.read_text(encoding="utf-8" ) p.write_bytes(b"binary data" ) data = p.read_bytes() p.rename("new_name.txt" ) p.replace("another_dir/file.txt" )
12.3 JSON 文件操作
import jsondata = { "name" : "张三" , "age" : 18 , "hobbies" : ["读书" , "编程" ], "address" : {"city" : "北京" , "district" : "海淀" } } 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) print (loaded["name" ]) print (loaded["hobbies" ]) json_str = json.dumps(data, ensure_ascii=False ) parsed = json.loads(json_str) def load_json_safe (filepath, default=None ): try : with open (filepath, "r" , encoding="utf-8" ) as f: return json.load(f) except (FileNotFoundError, json.JSONDecodeError): return default
12.4 CSV 文件操作
import csvstudents = [ ["姓名" , "年龄" , "成绩" ], ["张三" , 18 , 90 ], ["李四" , 20 , 85 ], ["王五" , 19 , 92 ], ] with open ("students.csv" , "w" , encoding="utf-8-sig" , newline="" ) as f: writer = csv.writer(f) writer.writerows(students) with open ("students.csv" , "r" , encoding="utf-8-sig" ) as f: reader = csv.reader(f) for row in reader: print (row) records = [ {"姓名" : "张三" , "年龄" : 18 , "成绩" : 90 }, {"姓名" : "李四" , "年龄" : 20 , "成绩" : 85 }, ] with open ("students.csv" , "w" , encoding="utf-8-sig" , newline="" ) as f: writer = csv.DictWriter(f, fieldnames=["姓名" , "年龄" , "成绩" ]) writer.writeheader() writer.writerows(records) with open ("students.csv" , "r" , encoding="utf-8-sig" ) as f: reader = csv.DictReader(f) for row in reader: print (row["姓名" ], row["成绩" ])
十三、标准库
13.1 os 与 sys
import osimport sysprint (os.name) print (os.getcwd()) os.chdir("/tmp" ) print (os.listdir("." )) os.makedirs("a/b/c" , exist_ok=True ) os.remove("file.txt" ) os.rename("old.txt" , "new.txt" ) print (os.environ.get("PATH" )) os.environ["MY_VAR" ] = "hello" os.system("echo hello" ) print (sys.version) print (sys.platform) print (sys.argv) print (sys.path) sys.exit(0 )
13.2 datetime
from datetime import datetime, date, time, timedeltanow = datetime.now() today = date.today() dt = datetime(2024 , 1 , 15 , 10 , 30 , 0 ) d = date(2024 , 1 , 15 ) print (now.year, now.month, now.day)print (now.hour, now.minute, now.second)print (now.weekday()) delta = timedelta(days=7 , hours=3 ) next_week = now + delta yesterday = today - timedelta(days=1 ) start = datetime(2024 , 1 , 1 ) end = datetime(2024 , 12 , 31 ) diff = end - start print (diff.days) print (now.strftime("%Y-%m-%d %H:%M:%S" )) print (now.strftime("%Y年%m月%d日" )) dt = datetime.strptime("2024-01-15" , "%Y-%m-%d" ) dt = datetime.strptime("2024/01/15 10:30" , "%Y/%m/%d %H:%M" ) timestamp = now.timestamp() dt = datetime.fromtimestamp(timestamp)
13.3 re(正则表达式)
import retext = "我的邮箱是 alice@example.com,电话是 138-1234-5678" match = re.search(r'\w+@\w+\.\w+' , text)if match : print (match .group()) print (match .start()) print (match .end()) phones = re.findall(r'\d{3}-\d{4}-\d{4}' , text) print (phones) new_text = re.sub(r'\d{3}-\d{4}-\d{4}' , '***-****-****' , text) print (new_text)pattern = r'(\w+)@(\w+)\.(\w+)' match = re.search(pattern, text)if match : print (match .group(0 )) print (match .group(1 )) print (match .group(2 )) print (match .group(3 )) pattern = r'(?P<user>\w+)@(?P<domain>\w+)\.(?P<tld>\w+)' match = re.search(pattern, text)if match : print (match .group("user" )) print (match .group("domain" )) email_pattern = re.compile (r'\w+@\w+\.\w+' , re.IGNORECASE) result = email_pattern.findall(text) """ . 匹配任意字符(除换行符) ^ 匹配字符串开头 $ 匹配字符串结尾 * 0 个或多个 + 1 个或多个 ? 0 个或 1 个 {n} 恰好 n 个 {n,m} n 到 m 个 [] 字符集合 [^] 取反字符集合 | 或 () 分组 \d 数字 [0-9] \D 非数字 \w 字母数字下划线 [a-zA-Z0-9_] \W 非 \w \s 空白字符 \S 非空白字符 """
import itertoolsimport functoolsfor item in itertools.chain([1 , 2 ], [3 , 4 ], [5 , 6 ]): print (item) for pair in itertools.product([1 , 2 ], ['a' , 'b' ]): print (pair) for c in itertools.combinations([1 , 2 , 3 ], 2 ): print (c) for p in itertools.permutations([1 , 2 , 3 ], 2 ): print (p) data = [("A" , 1 ), ("A" , 2 ), ("B" , 3 ), ("B" , 4 )] for key, group in itertools.groupby(data, key=lambda x: x[0 ]): print (key, list (group)) for item in itertools.islice(range (100 ), 5 , 10 ): print (item) total = functools.reduce(lambda acc, x: acc + x, [1 , 2 , 3 , 4 , 5 ]) print (total) def power (base, exponent ): return base ** exponent square = functools.partial(power, exponent=2 ) cube = functools.partial(power, exponent=3 ) print (square(5 )) print (cube(3 )) @functools.lru_cache(maxsize=128 ) def fibonacci (n ): if n < 2 : return n return fibonacci(n - 1 ) + fibonacci(n - 2 ) print (fibonacci(50 )) @functools.cache def factorial (n ): return 1 if n == 0 else n * factorial(n - 1 )
十四、模块化与包
14.1 模块
"""数学工具模块""" PI = 3.14159 def circle_area (radius ): """计算圆的面积""" return PI * radius ** 2 def circle_perimeter (radius ): """计算圆的周长""" return 2 * PI * radius if __name__ == "__main__" : print (circle_area(5 )) import math_utilsprint (math_utils.circle_area(5 ))from math_utils import circle_area, PIprint (circle_area(5 ))from math_utils import circle_area as areaprint (area(5 ))
14.2 包
from .utils.string_utils import format_namefrom .utils.math_utils import circle_areafrom .models.user import Userimport my_packagemy_package.format_name("zhang san" ) from my_package.utils import string_utilsstring_utils.format_name("zhang san" ) from my_package.models.user import Useruser = User("张三" , 18 )
14.3 虚拟环境与项目结构
推荐的项目结构: my_project/ ├── venv/ # 虚拟环境(不提交到版本控制) ├── src/ # 源代码 │ └── my_project/ │ ├── __init__.py │ ├── main.py │ ├── config.py │ ├── models/ │ │ ├── __init__.py │ │ └── user.py │ └── utils/ │ ├── __init__.py │ └── helpers.py ├── tests/ # 测试代码 │ ├── __init__.py │ └── test_user.py ├── requirements.txt # 依赖列表 ├── README.md # 项目说明 └── .gitignore # Git 忽略文件
十五、常用算法实现
15.1 排序算法
def bubble_sort (arr ): n = len (arr) for i in range (n): swapped = False for j in range (0 , n - i - 1 ): if arr[j] > arr[j + 1 ]: arr[j], arr[j + 1 ] = arr[j + 1 ], arr[j] swapped = True if not swapped: break return arr def insertion_sort (arr ): for i in range (1 , len (arr)): key = arr[i] j = i - 1 while j >= 0 and arr[j] > key: arr[j + 1 ] = arr[j] j -= 1 arr[j + 1 ] = key return arr def quick_sort (arr ): if len (arr) <= 1 : return arr pivot = arr[len (arr) // 2 ] left = [x for x in arr if x < pivot] middle = [x for x in arr if x == pivot] right = [x for x in arr if x > pivot] return quick_sort(left) + middle + quick_sort(right) def merge_sort (arr ): if len (arr) <= 1 : return arr mid = len (arr) // 2 left = merge_sort(arr[:mid]) right = merge_sort(arr[mid:]) return merge(left, right) def merge (left, right ): result = [] i = j = 0 while i < len (left) and j < len (right): if left[i] <= right[j]: result.append(left[i]) i += 1 else : result.append(right[j]) j += 1 result.extend(left[i:]) result.extend(right[j:]) return result arr = [5 , 2 , 8 , 1 , 9 ] sorted_arr = sorted (arr) arr.sort() arr.sort(key=lambda x: -x) arr.sort(key=abs )
15.2 搜索算法
def linear_search (arr, target ): for i, item in enumerate (arr): if item == target: return i return -1 def binary_search (arr, target ): left, right = 0 , len (arr) - 1 while left <= right: mid = (left + right) // 2 if arr[mid] == target: return mid elif arr[mid] < target: left = mid + 1 else : right = mid - 1 return -1 import bisectarr = [1 , 3 , 5 , 7 , 9 , 11 ] print (bisect.bisect_left(arr, 7 )) print (bisect.bisect_right(arr, 7 )) bisect.insort(arr, 6 ) print (arr)
15.3 递归
def factorial (n ): if n == 0 : return 1 return n * factorial(n - 1 ) def fib (n ): if n < 2 : return n return fib(n - 1 ) + fib(n - 2 ) from functools import lru_cache@lru_cache(maxsize=None ) def fib (n ): if n < 2 : return n return fib(n - 1 ) + fib(n - 2 ) def fib_dp (n ): if n < 2 : return n a, b = 0 , 1 for _ in range (2 , n + 1 ): a, b = b, a + b return b class TreeNode : def __init__ (self, val=0 , left=None , right=None ): self .val = val self .left = left self .right = right def inorder (root ): """中序遍历:左-根-右""" if root is None : return [] return inorder(root.left) + [root.val] + inorder(root.right) def preorder (root ): """前序遍历:根-左-右""" if root is None : return [] return [root.val] + preorder(root.left) + preorder(root.right)
十六、代码规范与调试
16.1 PEP8 规范要点
def good_function (): if True : pass result = (first_value + second_value + third_value) class MyClass : def method_one (self ): pass def method_two (self ): pass def top_level_function (): pass import osimport sysimport requestsimport numpy as npfrom my_module import my_functionvariable_name = 1 CONSTANT_NAME = 2 def function_name (): pass class ClassName : pass x = 1 y = x + 1 lst[1 :2 ] def f (x, y=1 ): pass f(x=1 , y=2 )
16.2 类型提示
def greet (name: str ) -> str : return f"Hello, {name} " def add (a: int , b: int ) -> int : return a + b def get_ratio (total: int , part: int ) -> float : return part / total def process (items: list [int ] ) -> dict [str , int ]: return {"sum" : sum (items), "count" : len (items)} from typing import List , Dict , Tuple , Optional , Union def old_style (items: List [int ] ) -> Dict [str , int ]: return {"sum" : sum (items)} def find_user (user_id: int ) -> Optional [str ]: if user_id == 1 : return "张三" return None def parse (value: Union [str , int ] ) -> str : return str (value) class User : def __init__ (self, name: str , age: int ) -> None : self .name = name self .age = age def get_info (self ) -> str : return f"{self.name} ,{self.age} 岁"
16.3 调试技巧
print (f"DEBUG: value={value} , type={type (value)} " )def divide (a, b ): assert b != 0 , f"除数不能为0,收到 b={b} " return a / b import logginglogging.basicConfig( level=logging.DEBUG, format ="%(asctime)s - %(name)s - %(levelname)s - %(message)s" , handlers=[ logging.StreamHandler(), logging.FileHandler("app.log" ), ] ) logger = logging.getLogger(__name__) logger.debug("调试信息,开发时使用" ) logger.info("一般信息" ) logger.warning("警告,不影响运行" ) logger.error("错误,影响部分功能" ) logger.critical("严重错误,程序无法继续" ) import pdbdef buggy_function (data ): pdb.set_trace() result = data * 2 return result def buggy_function (data ): breakpoint () return data * 2
16.4 单元测试
import unittestdef add (a, b ): return a + b def divide (a, b ): if b == 0 : raise ZeroDivisionError("除数不能为0" ) return a / b class TestMathFunctions (unittest.TestCase): def setUp (self ): """每个测试方法执行前调用""" self .numbers = [1 , 2 , 3 , 4 , 5 ] def tearDown (self ): """每个测试方法执行后调用""" pass def test_add_positive (self ): self .assertEqual(add(2 , 3 ), 5 ) self .assertEqual(add(0 , 0 ), 0 ) def test_add_negative (self ): self .assertEqual(add(-1 , -2 ), -3 ) self .assertEqual(add(-1 , 1 ), 0 ) def test_divide_normal (self ): self .assertEqual(divide(10 , 2 ), 5 ) self .assertAlmostEqual(divide(1 , 3 ), 0.333 , places=3 ) def test_divide_by_zero (self ): with self .assertRaises(ZeroDivisionError): divide(10 , 0 ) def test_add_is_not_multiply (self ): self .assertNotEqual(add(2 , 3 ), 6 ) def test_result_type (self ): self .assertIsInstance(add(1 , 2 ), int ) if __name__ == "__main__" : unittest.main()
总结
知识体系速查
Python 知识体系 ├── 环境配置 → 安装、虚拟环境、pip ├── 基础语法 → 注释、缩进、导入、变量命名、输入输出 ├── 数据类型 → int/float/bool/str/None、类型检查与转换、可变与不可变 ├── 字符串 → 索引切片、常用方法、格式化、转义字符 ├── 数字运算 → 算术运算符、math模块、进制转换 ├── 流程控制 → if/elif/else、match、for、while、推导式 ├── 函数 → 定义、参数类型、作用域、闭包、装饰器、lambda、生成器 ├── 数据结构 → list、tuple、dict、set、collections模块 ├── 面向对象 → 类与对象、继承、封装、property、魔法方法、抽象基类 ├── 异常处理 → try/except/else/finally、自定义异常、上下文管理器 ├── 文件操作 → 读写、pathlib、JSON、CSV ├── 标准库 → os/sys、datetime、re、itertools、functools ├── 模块化 → 模块、包、项目结构 ├── 算法 → 排序、搜索、递归 └── 工程实践 → PEP8、类型提示、日志、调试、单元测试
常见问题速查
问题
解决方案
浮点数精度问题
使用 decimal 模块,或 round() 处理显示
可变默认参数陷阱
默认参数使用 None,函数内判断后再创建
循环中的闭包陷阱
用默认参数 lambda x=i: x 捕获当前值
浅拷贝与深拷贝混淆
嵌套结构用 copy.deepcopy(),简单结构用 .copy()
修改列表时遍历列表
遍历副本 for item in lst.copy(): 或用推导式过滤
大文件内存溢出
使用生成器逐行处理
字典键不存在
使用 .get(key, default) 或 defaultdict
字符串拼接性能差
使用 "".join(list) 代替 +=
递归层数过深
改用迭代,或 sys.setrecursionlimit() 调整限制
中文文件乱码
指定 encoding="utf-8",CSV 用 utf-8-sig