错误: 此上下文中不允许函数定义。_python上下文管理器,自定义模板及注意事项...

本文介绍了Python的上下文管理器,包括其作用、with语句的使用,以及如何通过类和函数自定义上下文管理器。重点讲解了__enter__和__exit__方法的实现细节,以及它们对错误处理的影响。最后,通过示例展示了自定义上下文管理器的常见用法和陷阱。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上下文管理器

  • 是一个对象
  • 这个对象有两个特殊的方法 __enter__() 和 __exit__()
  • 通过 with 语句调用这个对象时,能自动执行两个特殊方法进入和退出对象,代码非常简洁、方便
  • 一般这样写:with 对象 as 标识符:

1、首先得了解一下异常处理

前面文章讲解过,详细可以点击【异常处理的四种方法,不只是try】文章

异常 try

try:    f = open('file.txt', 'r')    print(f.read())  # 返回:文本内容finally:    f.close()

2、with 语句:可以替代 try ... finally ... 语句,使代码更简洁

用 with 语句代替 try 的写法

with open('file.txt', 'r') as f:    print(f.read())  # 返回:文本内容

说 with 语句执行过程前,需要了解两个类的特殊方法,详细了解可点击【类的特殊方法,自动调用】

特殊方法说明

  • 以下两个方法只能同时使用,只用做 with 语句才会自动调用
  • 自动调用,无需我们自己编写

特殊方法理解

  • __enter__:此方法的返回值是上下文管理器对象,会绑定到 as 子句中的标识符 f
  • __exit__:关闭上下文管理器对象,需不需要抛出错误,由返回值决定

说一下 with语句 的执行过程

程序遇到 with 就判定后面是一个上下文管理器

此例中打开 file.txt 文件作为一个上下文管理器对象

  1. 对 open('file.txt', 'r', encoding='utf8') 求值,获得一个上下文管理器对象
  2. 调用上下文管理器的 __enter__ 方法,并把对象赋值给 as 子句中的标识符 f
  3. 执行语句块 print(f.read())
  4. 调用上下文管理器的 __exit__ 方法,关闭上下文管理器对象 f

3、自定义上下文管理器-通过类来实现

需要在类中自定义手动实现 __enter__ 和 __exit__ 方法

__enter__() 定义方法:返回self(对象本身),不返回无法执行 drink 方法;返回其他对象,执行其他对象的方法

__exit__() 定义方法:不返回 ,程序会正常报代码错误;返回 False,程序会正常报代码错误;返回 True,程序会忽略代码错误

下面看三个示例

示例一:__exit__()不返回值

8a243b4e1f6459b39b0433f1f6decdd8.png

代码正常报错

示例二:__exit__()返回值 False

b76cb1eb46dd866182e2ac5d71d46cd5.png

代码正常报错

示例三:__exit__()返回值 True

e3f33c3d0654dc72459f4e22fe4f02d2.png

代码不报错

总结:自定义上下文管理器,类的实现方式

  • __enter__() 方法,必须返回 self或者其他对象,不返回的话 with ... as f: f 的值为 None,f 无法执行对象方法,就没有什么意义了
  • __exit__() 方法,不返回值,对于代码报错,程序会自动报错
  • __exit__() 方法,返回 False,对于代码报错,程序会自动报错
  • __exit__() 方法,返回 True,对于代码报错,程序不报错,正常执行,所以返回 True 时要特别注意

4、自定义上下文管理器-通过函数来实现

需要用装饰器和生成器函数

两种情况:finally中没有 return;finally中有 return

from contextlib import contextmanager  # python内置模块

示例一:contextlib装饰器,finally 中不返回

70235022d62d3c7a706e29d1483feb2b.png

示例二:contextlib装饰器,finally 中返回 True、False、空、其他

2d6cb77856f623f42c3d20dc8b0ccd37.png

代码不报错

总结:自定义上下文管理器,函数的实现方式

  • 需要 contextmanager 装饰器
  • 需要一个生成器,yield 返回对象
  • yield 要用try ... finally 语句包裹,不然对象报错,后面不执行
  • finally 语句不返回值,代码正常报错
  • finally 语句有返回,代码不报错

喜欢的小伙伴,请关注 python一看便懂。

4108d7c3f39c9e7007dc29228271eacc.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值