news 2026/11/5 1:56:40

Python 进阶神器:拷贝、迭代器、生成器、装饰器,老哥一次给你补齐

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 进阶神器:拷贝、迭代器、生成器、装饰器,老哥一次给你补齐

基础语法你会了,但离 "写优雅的 Python" 还差几个高级武器。老哥这篇把拷贝、迭代器、生成器、闭包、装饰器一次补齐。

一、浅拷贝 vs 深拷贝

先分清三种 "复制":

  • 直接赋值:只是引用的别名,不产生拷贝;
  • 浅拷贝:拷贝父对象,但内部子对象还是共享(只有第一层独立);
  • 深拷贝:父对象和子对象全都独立拷贝。

浅拷贝的三种方式:切片[:]、工厂函数list()/set()、copy.copy()。

用内存地址看深浅拷贝的区别(核心:可变类型的子对象是否独立):

import copy list1 = [1, 2, 3, [100, 200, 300]] list2 = copy.copy(list1) # 浅拷贝 print(id(list2[3]) == id(list1[3])) # True 子列表还是同一个! list1[3].append(400) # 改子列表 print(list2) # [1, 2, 3, [100, 200, 300, 400]] 浅拷贝也被改了! list3 = copy.deepcopy(list1) # 深拷贝 print(id(list3[3]) == id(list1[3])) # False 子列表独立了! list1[3].append(500) print(list3) # 深拷贝不受影响

特殊情况:数字、字符串等 "原子类型" 无法拷贝(copy 后地址不变);只含原子类型的元组深拷贝也不会变(地址不变)。

二、迭代器:记住位置、往前遍历

迭代器是一个能记住遍历位置的对象,只能往前不会后退。字符串、列表、元组都能创建迭代器。

用iter()创建、next()取下一个,取完抛StopIteration:

lst = [1, 2, 3] it = iter(lst) print(next(it)) # 1 print(next(it)) # 2 print(next(it)) # 3 print(next(it)) # StopIteration!

判断可迭代 / 迭代器:

from collections.abc import Iterable, Iterator print(isinstance([], Iterable)) # True 列表可迭代 print(isinstance([], Iterator)) # False 但本身不是迭代器 print(isinstance((x for x in range(10)), Iterator)) # True 生成器是迭代器

自定义迭代器:实现__iter__()(返回自己)和__next__()(取元素,取完抛StopIteration):

class Reverse: def __init__(self, data): self.data = data self.index = len(data) def __iter__(self): return self def __next__(self): if self.index == 0: raise StopIteration self.index -= 1 return self.data[self.index] for char in Reverse([2, 3, 5, 7]): print(char) # 7 5 3 2

三、生成器:按需产生值,省内存

生成器(generator)是创建迭代器的简单工具,用yield替代return。每次遇到yield暂停、保存状态,下次从暂停处继续。最大优势:按需生成,避免一次性占用大量内存。

两种创建方式:

# 方式一:推导式(注意是圆括号) gen = (x for x in range(5)) print(gen) # <generator object ...> for x in gen: print(x) # 方式二:yield 函数 def fibo(): # 斐波那契 a, b = 0, 1 while True: yield b a, b = b, a + b f = fibo() print(next(f)) # 1 print(next(f)) # 1 print(next(f)) # 2

send():向生成器 "发送" 值,实现两个任务交替执行:

def gen(): task_id = 0 int_value = 0 char_value = "A" while True: match task_id: case 0: task_id = yield int_value # 返回并接收 send 的值 int_value += 1 case 1: task_id = yield char_value char_value = chr(ord(char_value) + 1) case _: task_id = yield g = gen() print(next(g)) # 0 print(g.send(1)) # A print(g.send(0)) # 1 print(g.send(1)) # B

注意:第一次启动生成器要用send(None)(此时没有 yield 可接收值)。

四、闭包:函数 "记住" 外层变量

函数执行完,内部变量本应销毁。但闭包能让外层函数的变量被保存、重复使用,同时避免全局变量污染。

构建闭包三条件:外层函数定义内层函数、内层用到外层变量、外层把内层返回。

def linear(a, b): # 外层 def inner(x): # 内层 return a * x + b # 用到外层变量 a、b return inner # 返回内层 y1 = linear(1, 1) print(y1(5)) # 6 虽然 linear 已结束,但 a、b 还在 # 查看闭包保存的值 print(y1.__closure__[0].cell_contents) # 1 print(y1.__closure__[1].cell_contents) # 1

五、装饰器:不改原函数,动态加功能

装饰器接收一个函数,返回一个包装后的新函数,从而不修改原代码就给函数加功能。

最基础的装饰器(让sqrt先求绝对值,负数也能开根号):

from math import sqrt def decorator(f): def inner(x): x = abs(x) # 加功能:先取绝对值 return f(x) return inner @decorator # 等价于 func = decorator(func) def func(x): return sqrt(x) print(func(-4)) # 2.0

多层装饰器:离函数最近的先装饰,从内到外:

@get_integer @get_absolute def func(x): return sqrt(x)

带参数的装饰器(如 "开 n 次方"):

def times(n): def get_absolute(f): def inner(x): x = abs(x) for i in range(n): x = f(x) return x return inner return get_absolute @times(2) # 开两次方 def func(x): return sqrt(x) print(func(-16)) # 2.0

类装饰器:实现__call__()的类也能当装饰器:

class DecoratorClass: def __init__(self, f): self.f = f def __call__(self, x): x = abs(x) return self.f(x) @DecoratorClass def func(x): return sqrt(x) print(func(-4)) # 2.0

老哥收尾

一句话总结这批 "进阶神器":

浅拷贝共享子对象、深拷贝全独立;迭代器记住位置只能往前;生成器用 yield 按需生成省内存;闭包记住外层变量;装饰器不改原函数就能加功能。

下一篇讲进程与线程—— 让程序 "多任务并行"。有问题随时回来找老哥。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/5 1:56:38

基于Springboot3 + Vue3实现的同城兴趣活动组局平台

项目描述本项目是一个面向校园与社区场景的活动发布与报名管理平台&#xff0c;围绕“活动发起—报名参与—过程管理—数据统计”的完整链路进行设计&#xff0c;覆盖访客、普通用户、活动发起人和管理员四类角色&#xff0c;力求让活动组织更高效、参与体验更顺畅。平台按角色…

作者头像 李华
网站建设 2026/11/5 1:55:17

「追问意识,证本寻源」

意识“难问题”&#xff0c;是当代科学最具挑战性的前沿之一&#xff1a;主观体验从何而生&#xff0c;其物理本源至今未有定论。 丘脑被认为可能是意识觉知的核心锚点&#xff0c;在全脑信息汇聚、意识产生中发挥关键作用。多项前沿研究表明&#xff0c;丘脑核团活动与意识水…

作者头像 李华
网站建设 2026/11/5 1:55:14

业财税票档一体化的协同效率从哪里来——发票模块如何完成业务语言到财务语言的自动翻译

业财税票档一体化的协同效率从哪里来 ——发票模块如何完成业务语言到财务语言的自动翻译 把合同、采购、销售、资金、报销、档案逐个打通&#xff0c;只是“系统连着系统”&#xff1b;真正难的是让同一笔业务在不同部门被读出同一个意思。业务侧说“货已发、服务已交付”&…

作者头像 李华
网站建设 2026/11/5 1:55:12

DeepSeek LeetCode 516. 最长回文子序列 Java实现

LeetCode 516. 最长回文子序列 Java 实现 题意 给定字符串 s&#xff0c;求其最长回文子序列的长度。 注意区分"子序列"和"子串"&#xff1a;子序列不要求连续&#xff0c;可以跳跃&#xff08;如 bbbab 的最长回文子序列是 bbbb&#xff0c;长度 4&…

作者头像 李华
网站建设 2026/11/5 1:55:10

【共创稿事节】HarmonyOS 7.0 Navigation路由表:从接入到生产验证

Navigation 是鸿蒙官方点名的路由方案,可健康菜谱助手接入它时,官方示例没有回答的问题比给的多:路由表里塞几十个页面怎么管理、跨模块注册路由表怎么避免冲突、NavDestination 的生命周期和页面栈怎么配合、动态路由(参数决定目标页)怎么落地。这篇复盘 Navigation 路由表从接…

作者头像 李华