Python 进阶知识体系:2
Python 进阶知识体系2这篇笔记整理了 Python 字符串格式化、生成器、深浅拷贝、猴子补丁、元类等核心进阶知识点。每个主题都配有场景化记忆法和实战示例帮你真正理解并记住这些容易混淆的概念。一、字符串格式化从 % 到 f-string1.1 % 格式化的核心语法GNU\s Not %s %% % UNIX这句话里%扮演了两个角色%s占位符表示这里要放一个字符串% UNIX格式化操作符意思是把UNIX填进前面的占位符%%转义字符表示输出一个真正的%执行结果GNUs Not UNIX %1.2 三种格式化方式对比方式语法适用场景特点% 格式化Hello %s % name老代码兼容语法简单但不够灵活str.formatHello {}.format(name)Python 3.0功能强大支持位置和关键字f-stringfHello {name}Python 3.6最简洁性能最优经验之谈新项目直接用 f-string老代码遇到 % 格式化也别慌记住%s是占位符%%是转义就行。1.3 常见占位符速查%d%42# 整数%f%3.14# 浮点数%s%hello# 字符串%x%255# 十六进制%.2f%3.14159# 保留两位小数二、生成器懒人的糖果工厂2.1 生成器的核心思想生成器就像一家按需生产的糖果工厂——顾客要一颗你才做一颗不提前囤货节省内存。defmake_candies():foriinrange(1,4):yieldf糖果{i}# 产出一颗暂停candy_genmake_candies()# 创建工厂但没开始生产next(candy_gen)# 产出糖果1next(candy_gen)# 产出糖果2next(candy_gen)# 产出糖果3next(candy_gen)# StopIteration没货了2.2 yield vs return 的区别对比项yieldreturn作用暂停函数保留状态结束函数返回值调用次数可多次调用只能调用一次内存占用按需生成极小一次性返回可能很大后续代码yield之后的代码下次继续执行return之后的代码不会执行2.3 StopIteration不是错误是信号很多人误以为StopIteration是一个错误其实它是迭代器用来喊我下班了的标准口号。next()听到这个口号会报错除非你处理了for循环听到这个口号会乖乖收工不会把异常展示给你看# 手动处理 StopIterationgenmake_candies()whileTrue:try:print(next(gen))exceptStopIteration:break# 正常结束不是错误2.4 生成器表达式除了用yield定义生成器函数还可以用生成器表达式# 列表推导贪婪占内存squares_list[x**2forxinrange(1000000)]# 生成器表达式懒惰省内存squares_gen(x**2forxinrange(1000000))记忆口诀“圆括号是懒人方括号是囤货王”2.5 实用场景读取大文件逐行读取不加载整个文件到内存无限序列斐波那契数列、质数生成数据管道A模块产数据 → B模块处理 → C模块输出三、深浅拷贝对象的独立程度3.1 赋值、浅拷贝、深拷贝的区别importcopy a[1,{age:10}]ba# 赋值共享同一个对象ca[:]# 浅拷贝新列表但内部元素共享引用dcopy.deepcopy(a)# 深拷贝完全独立互不影响a[1][age]12print(b)# [1, {age: 12}] —— 变了print(c)# [1, {age: 12}] —— 变了字典共享print(d)# [1, {age: 10}] —— 没变3.2 情景化理解想象你和朋友合租赋值你们共用一个冰箱你放进去的东西朋友也能看到浅拷贝你买了个新冰箱但冰箱里的牛奶还是同一瓶共享可变对象深拷贝你搬了新家有了完全独立的冰箱和所有东西3.3 什么时候用深拷贝当你需要修改嵌套的可变对象字典、列表等不影响原始数据保护数据完整性四、猴子补丁飞行中换引擎4.1 什么是猴子补丁猴子补丁Monkey Patching指的是在程序运行时动态修改已有的类、函数或模块的行为而无需修改其原始源代码。classCalculator:defadd(self,a,b):returnab# 猴子补丁把加法改成乘法defnew_add(self,a,b):returna*b Calculator.addnew_add calcCalculator()calc.add(2,3)# 输出 6而不是 54.2 为什么要用它紧急修复第三方库的 Bug官方还没发布新版本临时打补丁测试与 Mock隔离测试环境替换耗时操作功能扩展给无法修改源码的类动态添加功能4.3 风险与最佳实践主要风险破坏代码的可维护性和可预测性。别人读代码时根本不知道这个函数已经被调包了。最佳实践能用继承/装饰器解决的尽量不用猴子补丁如果非要用一定要写清晰的注释问题解决后及时清理掉记忆比喻猴子补丁就像创可贴——救急用的别把全身都缠满胶带。五、循环引用与垃圾回收5.1 什么是循环引用classMyObject:passobj1MyObject()obj2MyObject()obj1.otherobj2# obj1 引用 obj2obj2.otherobj1# obj2 引用 obj1 —— 形成循环.other是自定义的实例属性就像给对象起了个名字叫other指向另一个对象。互相赋值就形成了循环引用。5.2 为什么循环引用会导致内存泄漏Python 的引用计数机制无法处理循环引用obj1的引用计数 1被obj2.other引用obj2的引用计数 1被obj1.other引用永远不会归零内存不会被立即释放5.3 Python 的双轨制回收策略机制原理特点能否处理循环引用引用计数对象被引用时计数1引用失效时-1计数为0时立即回收实时性强速度快❌ 不能分代 GC定期扫描标记-清除不可达对象处理循环引用有延迟✅ 能经验之谈Python 主要靠引用计数即时清理靠 GC 定期打扫循环引用的垃圾。六、可调用对象让实例像函数一样工作6.1 什么是可调用对象在 Python 中能使用()进行调用的对象就是可调用对象函数function类class—— 调用类会创建实例实例对象 —— 如果该类定义了__call__方法6.2 通过__call__让实例可调用classNum:def__init__(self):self.num0def__call__(self):returnself.num nNum()n()# 调用 __call__返回 0 —— 实例变成了可调用对象记忆技巧__call__就像给对象装了个启动按钮按一下就能执行。七、collections 模块数据容器增强包7.1 核心类速查类名核心功能应用场景defaultdict访问不存在的键时自动初始化统计词频、分组聚合Counter统计元素出现次数 集合运算词频统计、投票计票OrderedDict记录插入顺序3.7 dict 默认有序需要明确有序语义的场景namedtuple创建轻量级、不可变对象替代简单类、返回多个值deque双端队列队列、栈、滑动窗口7.2 代码示例fromcollectionsimportdefaultdict,Counter,namedtuple# defaultdict —— 自动初始化ddefaultdict(int)d[a]1# 即使a不存在也自动创建并初始化为0# Counter —— 计数神器cCounter([a,b,a,c])c[a]# 2# namedtuple —— 命名元组Pointnamedtuple(Point,[x,y])pPoint(1,2)p.x# 17.3 情景化记忆defaultdict健忘症患者的备忘录自动帮你记下来Counter超市收银机不仅能数还能做集合运算namedtuple身份证发出去就不能改但每个人有清晰的名字字段八、元类类的工厂8.1 什么是元类元类metaclass是创建类的类。在 Python 中type是所有类的元类。classMeta(type):def__new__(cls,name,bases,dct):dct[version]1.0# 动态添加类属性returnsuper().__new__(cls,name,bases,dct)classBase(metaclassMeta):passBase.version# 1.0 —— 元类在创建类时注入的8.2super()在元类中的作用super().__new__()在元类中实际调用的是type.__new__()负责真正创建类对象。你可以把这个过程想成一条流水线Meta.__new__先改图纸修改类字典super().__new__()把图纸送到type总装厂type按图纸造出类对象记忆比喻type是总装厂Meta是改装车间super()是总装厂的联络员。8.3 子类继承元类子类会自动继承父类的元类classChild(Base):# 继承了 Base 的元类 MetapassChild.version# 1.0 —— 同样被注入了 version 属性九、文件操作与 open() 模式9.1 常用文件模式模式含义说明r只读默认模式w写入会清空原文件a追加在文件末尾添加b二进制与其他模式组合使用读写与其他模式组合使用9.2 模式组合示例open(file.txt,r)# 文本只读open(file.txt,rb)# 二进制只读open(file.txt,w)# 文本写入清空open(file.txt,wb)# 二进制写入清空open(file.txt,a)# 文本追加open(file.txt,ab)# 二进制追加正确答案open(file.txt,r)# 文本读写记忆口诀r读 w写 a追加b是二进制 t是文本。十、asyncio异步编程入门10.1asyncio.sleep(0)的奥秘很多人以为sleep(0)就是不休息但在异步编程中它的核心目的恰恰是释放 CPU 控制权。importasyncioasyncdeflong_task():foriinrange(1000000):do_something(i)ifi%10000:awaitasyncio.sleep(0)# 让出控制权让其他协程有机会运行原理sleep(0)向事件循环注册了一个下一轮迭代时立刻响的闹钟当前协程暂停事件循环去执行其他就绪的协程没有其他任务时再回来继续执行记忆比喻sleep(1)是我排会儿队等1分钟再来sleep(0)是我不排队了你先让后面的人办。10.2 异步编程的核心概念协程Coroutine可以暂停和恢复的函数事件循环Event Loop协程的调度器await暂停当前协程等待另一个协程完成非阻塞不会让整个程序卡住十一、math 模块数学计算利器11.1 常用常量和函数常量/函数数学含义示例math.pi圆周率 πmath.pi ≈ 3.14159math.e自然常数 emath.e ≈ 2.71828math.exp(x)指数函数 e^xmath.exp(2) ≈ 7.389math.log(x)自然对数 ln(x)math.log(math.e) 1math.pow(x, y)x 的 y 次方math.pow(2, 3) 811.2math.exp()vsmath.pow()math.exp(x)专门计算 e^x精度更高速度更快math.pow(x, y)计算任意底数的幂最佳实践计算 e 的幂时用math.exp()其他幂运算用math.pow()。十二、函数参数进阶12.1*在参数列表中的作用*在参数列表中表示后面的参数必须使用关键字参数传递。deffun(a,*,b):print(b)fun(1,b2)# ✅ 正确b用关键字参数fun(1,2)# ❌ 错误b必须用关键字参数fun(1,2,3,4)# ❌ 错误参数不匹配12.2 字典的 get() 方法info{name:班长,id:100}info.get(age)# None没有默认值info.get(age,18)# 18有默认值结语Python 的进阶知识就像一张网各个知识点之间互相联系。理解这些概念不仅能让你写出更高效、更优雅的代码也是面试中展示技术深度的重要素材。学习的过程就像拼图——每个知识点都是一块碎片当你把它们拼在一起时就能看到完整的画面。保持好奇心多写代码多踩坑你会越来越接近这门语言的本质。最后提醒这篇笔记适合反复阅读和实践。每次读都会有新的理解因为 Python 的深度远超表面。