京公网安备 11010802034615号
经营许可证编号:京B2-20210330
Python with语句上下文管理器两种实现方法分析
本文实例讲述了Python with语句上下文管理器。分享给大家供大家参考,具体如下:
在编程中会经常碰到这种情况:有一个特殊的语句块,在执行这个语句块之前需要先执行一些准备动作;当语句块执行完成后,需要继续执行一些收尾动作。例如,文件读写后需要关闭,数据库读写完毕需要关闭连接,资源的加锁和解锁等情况。
对于这种情况python提供了上下文管理器(Context Manager)的概念,可以通过上下文管理器来定义/控制代码块执行前的准备动作,以及执行后的收尾动作。
一、为何使用上下文管理器
1、不使用上下文管理器的情况
通过try...finally语句执行异常处理和关闭句柄的动作。
logger = open("log.txt", "w")
try:
logger.write('Hello ')
logger.write('World')
finally:
logger.close()
print logger.closed
2、使用上下文管理器
默认文件Python的内置file类型是支持上下文管理协议的。
使用上下文管理器with使得依据精简了很多。
with open("log.txt", "w") as logger:
logger.write('Hello ')
logger.write('World')
print logger.closed
二、实现上下文管理器实现上下文管理器有两种方式实现。方法一:类实现__enter__和__exit__方法。方法二:contextlib模块装饰器和生成器实现。
下面我们通过两种方法分别实现一个自定义的上下文管理器。
1、方法一:通过类实现__enter__和__exit__方法
class File(object):
def __init__(self, file_name, method):
self.file_obj = open(file_name, method)
def __enter__(self):
return self.file_obj
def __exit__(self, type, value, traceback):
self.file_obj.close()
with File('demo.txt', 'w') as opened_file:
opened_file.write('Hola!')
实现__enter__和__exit__方法后,就能通过with语句进行上下文管理。
a、底层都发生了什么?
1、with语句先暂存了File类的__exit__方法,然后它调用File类的__enter__方法。
2、__enter__方法打开文件并返回给with语句,打开的文件句柄被传递给opened_file参数。
3、with语句调用之前暂存的__exit__方法,__exit__方法关闭了文件。
b、异常处理
关于异常处理,with语句会采取哪些步骤。
1. 它把异常的type,value和traceback传递给__exit__方法
2. 它让__exit__方法来处理异常
3. 如果__exit__返回的是True,那么这个异常就被忽略。
4. 如果__exit__返回的是True以外的任何东西,那么这个异常将被with语句抛出。
异常抛出
#异常抛出,_exit__返回的是True以外的任何东西,那么这个异常将被with语句抛出
class File(object):
def __init__(self, file_name, method):
self.file_obj = open(file_name, method)
def __enter__(self):
return self.file_obj
def __exit__(self, type, value, traceback):
self.file_obj.close()
print "type:",type
print "value:",value
print "traceback:",traceback
with File('demo.txt', 'w') as opened_file:
opened_file.undefined_function('Hola!')
#output================================================
# type: <type 'exceptions.AttributeError'>
# value: 'file' object has no attribute 'undefined_function'
# traceback: <traceback object at 0x000000000262D9C8>
# opened_file.undefined_function('Hola!')
# AttributeError: 'file' object has no attribute 'undefined_function'
异常忽略:
#异常忽略,__exit__返回的是True,那么这个异常就被忽略。
class File(object):
def __init__(self, file_name, method):
self.file_obj = open(file_name, method)
def __enter__(self):
return self.file_obj
def __exit__(self, exception_type, exception_value, traceback):
print("Exception has been handled")
self.file_obj.close()
return True
with File('demo.txt', 'w') as opened_file:
opened_file.undefined_function('Hola!')
# output==================================
# Exception has been handled
2、方法二:contextlib模块装饰器和生成器实现
这种方式实现更优雅,我个人更喜欢这种方式。
yield之前的代码由__enter__方法执行,yield之后的代码由__exit__方法执行。本质上还是__enter__和__exit__方法。
# coding:utf-8
import contextlib
@contextlib.contextmanager
def myopen(filename, mode):
f = open(filename, mode)
try:
yield f.readlines()
except Exception as e:
print e
finally:
f.close()
if __name__ == '__main__':
with myopen(r'c:\ip2.txt', 'r') as f:
for line in f:
print line
3、with语句上多个下文关联
直接通过一个with语句打开多个上下文,即可同时使用多个上下文变量,而不必需嵌套使用with语句。
class File(object):
def __init__(self, file_name, method):
self.file_obj = open(file_name, method)
def __enter__(self):
return self.file_obj
def __exit__(self, exception_type, exception_value, traceback):
self.file_obj.close()
return True
with File('demo.txt', 'w') as f1,File('demo.txt','w') as f2:
print f1,f2
# Output============================# <open file 'demo.txt', mode
'w' at 0x000000000263D150> <open file 'demo.txt', mode 'w' at
0x000000000263D1E0>
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
在数据分析、质量控制、科研实验等场景中,数据波动性(离散程度)的精准衡量是判断数据可靠性、稳定性的核心环节。标准差(Stan ...
2026-01-29在数据分析、质量检测、科研实验等领域,判断数据间是否存在本质差异是核心需求,而t检验、F检验是实现这一目标的经典统计方法。 ...
2026-01-29统计制图(数据可视化)是数据分析的核心呈现载体,它将抽象的数据转化为直观的图表、图形,让数据规律、业务差异与潜在问题一目 ...
2026-01-29箱线图(Box Plot)作为数据分布可视化的核心工具,能清晰呈现数据的中位数、四分位数、异常值等关键统计特征,广泛应用于数据分 ...
2026-01-28在回归分析、机器学习建模等数据分析场景中,多重共线性是高频数据问题——当多个自变量间存在较强的线性关联时,会导致模型系数 ...
2026-01-28数据分析的价值落地,离不开科学方法的支撑。六种核心分析方法——描述性分析、诊断性分析、预测性分析、规范性分析、对比分析、 ...
2026-01-28在机器学习与数据分析领域,特征是连接数据与模型的核心载体,而特征重要性分析则是挖掘数据价值、优化模型性能、赋能业务决策的 ...
2026-01-27关联分析是数据挖掘领域中挖掘数据间潜在关联关系的经典方法,广泛应用于零售购物篮分析、电商推荐、用户行为路径挖掘等场景。而 ...
2026-01-27数据分析的基础范式,是支撑数据工作从“零散操作”走向“标准化落地”的核心方法论框架,它定义了数据分析的核心逻辑、流程与目 ...
2026-01-27在数据分析、后端开发、业务运维等工作中,SQL语句是操作数据库的核心工具。面对复杂的表结构、多表关联逻辑及灵活的查询需求, ...
2026-01-26支持向量机(SVM)作为机器学习中经典的分类算法,凭借其在小样本、高维数据场景下的优异泛化能力,被广泛应用于图像识别、文本 ...
2026-01-26在数字化浪潮下,数据分析已成为企业决策的核心支撑,而CDA数据分析师作为标准化、专业化的数据人才代表,正逐步成为连接数据资 ...
2026-01-26数据分析的核心价值在于用数据驱动决策,而指标作为数据的“载体”,其选取的合理性直接决定分析结果的有效性。选对指标能精准定 ...
2026-01-23在MySQL查询编写中,我们习惯按“SELECT → FROM → WHERE → ORDER BY”的语法顺序组织语句,直觉上认为代码顺序即执行顺序。但 ...
2026-01-23数字化转型已从企业“可选项”升级为“必答题”,其核心本质是通过数据驱动业务重构、流程优化与模式创新,实现从传统运营向智能 ...
2026-01-23CDA持证人已遍布在世界范围各行各业,包括世界500强企业、顶尖科技独角兽、大型金融机构、国企事业单位、国家行政机关等等,“CDA数据分析师”人才队伍遵守着CDA职业道德准则,发挥着专业技能,已成为支撑科技发展的核心力量。 ...
2026-01-22在数字化时代,企业积累的海量数据如同散落的珍珠,而数据模型就是串联这些珍珠的线——它并非简单的数据集合,而是对现实业务场 ...
2026-01-22在数字化运营场景中,用户每一次点击、浏览、交互都构成了行为轨迹,这些轨迹交织成海量的用户行为路径。但并非所有路径都具备业 ...
2026-01-22在数字化时代,企业数据资产的价值持续攀升,数据安全已从“合规底线”升级为“生存红线”。企业数据安全管理方法论以“战略引领 ...
2026-01-22在SQL数据分析与业务查询中,日期数据是高频处理对象——订单创建时间、用户注册日期、数据统计周期等场景,都需对日期进行格式 ...
2026-01-21