高级语法与特性
一、推导式(简洁生成容器,Pythonic 首选)
支持列表、字典、集合、元组推导,替代循环赋值,代码更简洁。
1. 列表推导式
语法:[表达式 for 变量 in 可迭代对象 if 条件]
# 普通循环lst=[]foriinrange(10):ifi%2==0:lst.append(i)# 列表推导式lst=[iforiinrange(10)ifi%2==0]print(lst)# [0, 2, 4, 6, 8]# 嵌套循环res=[(x,y)forxinrange(2)foryinrange(3)]print(res)# [(0,0),(0,1),(0,2),(1,0),(1,1),(1,2)]2. 字典推导式
# 键值互换d={"a":1,"b":2}new_d={v:kfork,vind.items()}print(new_d)# {1: 'a', 2: 'b'}3. 集合推导式
自动去重,用法和列表一致:
s={x%3forxinrange(10)}print(s)# {0, 1, 2}注意:没有元组推导式,
(x for x in ...)是生成器表达式。
二、迭代器 & 生成器(惰性求值,省内存)
1. 迭代器 Iterator
可被for遍历的对象,必须实现两个魔法方法:
__iter__():返回迭代器自身__next__():返回下一个元素,无元素时抛StopIteration
classMyIterator:def__init__(self,n):self.n=n self.cur=0def__iter__(self):returnselfdef__next__(self):ifself.cur<self.n:val=self.cur self.cur+=1returnvalraiseStopIteration# 遍历结束it=MyIterator(3)foriinit:print(i)# 0 1 22. 生成器 Generator
迭代器的语法糖,惰性生成数据,大数据场景必备,两种写法:
(1)生成器函数(yield)
函数遇到yield暂停,下次迭代从暂停处继续:
defgen(n):foriinrange(n):yieldi*2g=gen(4)print(next(g))# 0print(next(g))# 2fornuming:print(num)# 4 6(2)生成器表达式
写法类似列表推导式,把[]换成():
g=(x**2forxinrange(5))print(next(g))# 0核心优势:不一次性加载所有数据,海量数据不会内存溢出。
三、装饰器 Decorator
不修改原函数代码,动态扩展功能,底层是「函数接收函数、返回函数」。
1. 基础装饰器
defouter(func):# 内层函数包装原逻辑definner():print("执行前...")func()print("执行后...")returninner# 语法糖 @@outerdefhello():print("Hello Python")hello()2. 装饰带参数的函数
用*args, **kwargs兼容任意参数:
deftimer(func):definner(*args,**kwargs):importtime start=time.time()res=func(*args,**kwargs)print(f"耗时:{time.time()-start:.2f}s")returnresreturninner@timerdefadd(a,b):returna+bprint(add(1,2))3. 带参数的装饰器
外层多一层函数,用来接收装饰器参数:
defauth(role):defdecorator(func):definner():ifrole=="admin":func()else:print("权限不足")returninnerreturndecorator@auth(role="admin")defedit():print("编辑内容")edit()4. 保留原函数元信息
装饰器会覆盖原函数名称/文档,用functools.wraps修复:
fromfunctoolsimportwrapsdefouter(func):@wraps(func)definner():func()returninner四、高阶函数 & 匿名函数
1. 匿名函数lambda
语法:lambda 参数: 表达式,只能写单行表达式:
f=lambdax,y:x+yprint(f(1,3))# 42. 三大内置高阶函数
map:对序列每个元素执行函数
lst=[1,2,3]res=list(map(lambdax:x*2,lst))print(res)# [2,4,6]filter:过滤序列,保留结果为 True 的元素
lst=[1,2,3,4]res=list(filter(lambdax:x%2==0,lst))print(res)# [2,4]reduce:累积运算(需导入)
fromfunctoolsimportreducelst=[1,2,3,4]# 累加:((1+2)+3)+4res=reduce(lambdaa,b:a+b,lst)print(res)# 10五、上下文管理器with
自动申请/释放资源(文件、锁、数据库连接),避免漏关闭。
1. 基础用法(系统内置)
# 自动关闭文件,不用手动 f.close()withopen("test.txt","r",encoding="utf-8")asf:print(f.read())2. 自定义上下文管理器
实现__enter__和__exit__两个魔法方法:
classMyContext:def__enter__(self):print("进入上下文")returnself# as 接收的对象def__exit__(self,exc_type,exc_val,exc_tb):print("退出上下文")# 返回 True 表示吞掉异常returnFalsewithMyContext()asctx:print("业务逻辑")3. 快捷写法:@contextmanager
用装饰器快速生成上下文管理器:
fromcontextlibimportcontextmanager@contextmanagerdeftag(name):print(f"<{name}>")yieldprint(f"</{name}>")withtag("h1"):print("标题内容")六、变量作用域 & 关键字(nonlocal / global)
1.global:修改全局变量
a=10deffunc():globala a=20func()print(a)# 202.nonlocal:修改外层嵌套函数变量(非全局)
defouter():x=10definner():nonlocalx x=20inner()print(x)outer()# 20七、解包与星号用法(* / **)
1. 序列解包
a,b,c=[1,2,3]# 星号收集多个元素first,*mid,last=[1,2,3,4,5]print(first,mid,last)# 1 [2,3,4] 52. 函数参数
*args:接收位置参数,打包成元组**kwargs:接收关键字参数,打包成字典
deffunc(*args,**kwargs):print(args)# (1,2)print(kwargs)# {"name":"Tom"}func(1,2,name="Tom")3. 拆包传参
lst=[10,20]d={"a":1,"b":2}defadd(x,y):returnx+yprint(add(*lst))# 30八、魔术方法(内置方法,双下划线)
控制对象的运算、访问、打印等行为,列举高频常用:
classPerson:def__init__(self,name):self.name=name# 打印/str() 调用def__str__(self):returnf"姓名:{self.name}"# 下标取值:obj[0]def__getitem__(self,idx):returnself.name[idx]# 对象当作函数调用:obj()def__call__(self):print(f"我是{self.name}")p=Person("Alice")print(p)# 姓名:Aliceprint(p[0])# Ap()# 我是 Alice学习顺序建议
- 先练推导式、lambda、高阶函数(日常编码高频)
- 再学迭代器 + 生成器(处理大数据、流数据)
- 然后装饰器(日志、权限、缓存通用方案)
- 接着with 上下文管理器(资源管理)
- 最后吃透作用域、解包、魔术方法(面向对象进阶基础)
