今天,我第一次碰到了Python with语句。 我已经使用Python几个月了,甚至都不知道它的存在! 考虑到它的地位有些晦涩,我认为值得一问:

  1. Python with语句旨在用于什么?
  2. 你用它来做什么?
  3. 我需要了解任何陷阱,还是与其使用相关的常见反模式? 任何情况下,它是更好地利用try..finallywith
  4. 为什么没有更广泛地使用它?
  5. 哪些标准库类与之兼容?

#1楼

with语句适用于所谓的上下文管理器:

http://docs.python.org/release/2.5.2/lib/typecontextmanager.html

这个想法是通过在离开“ with”块之后进行必要的清理来简化异常处理。 某些python内置插件已经可以用作上下文管理器。


#2楼

参见PEP 343-'with'语句 ,最后有一个示例部分。

... Python语言的新语句“ with”使排除try / finally语句的标准用法成为可能。


#3楼

我会建议两个有趣的讲座:

  • PEP 343 “ with”声明
  • Effbot了解Python的“ with”语句

1. with语句用于使用上下文管理器定义的方法来包装块的执行。 这允许将常见的try...except...finally使用模式进行封装以方便重用。

2.您可以执行以下操作:

with open("foo.txt") as foo_file:data = foo_file.read()

要么

from contextlib import nested
with nested(A(), B(), C()) as (X, Y, Z):do_something()

或(Python 3.1)

with open('data') as input_file, open('result', 'w') as output_file:for line in input_file:output_file.write(parse(line))

要么

lock = threading.Lock()
with lock:# Critical section of code

3.我在这里看不到任何反模式。
引用Dive进入Python :

试试..最终是好的。 与更好。

4.我想这与程序员使用来自其他语言的try..catch..finally语句的习惯有关。


#4楼

第1、2和3点被合理地涵盖了:

4:它相对较新,仅适用于python2.6 +(或python2.5使用from __future__ import with_statement


#5楼

  1. 我相信这已经被我之前的其他用户回答了,所以我仅出于完整性的目的添加它: with语句通过将通用的准备工作和清理任务封装在所谓的上下文管理器中来简化异常处理。 可以在PEP 343中找到更多详细信息。 例如, open语句本身就是一个上下文管理器,它使您可以打开文件,只要在使用它的with语句的上下文中执行该文件,就可以保持打开状态,并在离开语句后立即将其关闭。上下文,无论您是由于异常还是在常规控制流程中离开了它。 因此, with语句可以以类似于C ++中的RAII模式的方式使用: with语句获取某些资源with并在离开with上下文时将其释放。

  2. 一些示例是:使用with open(filename) as fp: ,使用with lock: (其中lockthreading.Lock的实例)获取锁。 您也可以通过构建自己的上下文管理contextmanager从装饰contextlib 。 例如,当我不得不临时更改当前目录然后返回到原来的位置时,我经常使用它:

     from contextlib import contextmanager import os @contextmanager def working_directory(path): current_dir = os.getcwd() os.chdir(path) try: yield finally: os.chdir(current_dir) with working_directory("data/stuff"): # do something within data/stuff # here I am back again in the original working directory 

    这是另一个将sys.stdinsys.stdoutsys.stderr临时重定向到其他文件句柄并稍后将其还原的示例:

     from contextlib import contextmanager import sys @contextmanager def redirected(**kwds): stream_names = ["stdin", "stdout", "stderr"] old_streams = {} try: for sname in stream_names: stream = kwds.get(sname, None) if stream is not None and stream != getattr(sys, sname): old_streams[sname] = getattr(sys, sname) setattr(sys, sname, stream) yield finally: for sname, stream in old_streams.iteritems(): setattr(sys, sname, stream) with redirected(stdout=open("/tmp/log.txt", "w")): # these print statements will go to /tmp/log.txt print "Test entry 1" print "Test entry 2" # back to the normal stdout print "Back to normal stdout again" 

    最后,另一个示例创建一个临时文件夹并在离开上下文时清理它:

     from tempfile import mkdtemp from shutil import rmtree @contextmanager def temporary_dir(*args, **kwds): name = mkdtemp(*args, **kwds) try: yield name finally: shutil.rmtree(name) with temporary_dir() as dirname: # do whatever you want 

#6楼

Python with语句是C ++中常用的“ Resource Acquisition Is Initialization惯用语的内置语言支持。 旨在允许安全获取和释放操作系统资源。

with语句在作用域/块内创建资源。 您可以使用块中的资源编写代码。 当该块退出时,无论该块中代码的结果如何(即该块是正常退出还是由于异常而退出),资源都会被干净地释放。

Python库中的许多资源都遵循with语句所需的协议,因此可以立即使用。 但是,任何人都可以通过实施有据可查的协议来制作可在with语句中使用的资源: PEP 0343

每当您在应用程序中获取必须明确放弃的资源(例如文件,网络连接,锁等)时,都应使用它。


#7楼

反模式的一个例子可能是使用with在循环中时,它会更有效有with外循环

例如

for row in lines:with open("outfile","a") as f:f.write(row)

with open("outfile","a") as f:for row in lines:f.write(row)

第一种方法是为每一row打开和关闭文件,而第二种方法是一次打开和关闭文件,这可能会导致性能问题。


#8楼

再次为了完整性,我将为with语句添加最有用的用例。

我进行了大量的科学计算,对于某些活动,我需要使用Decimal库进行任意精度的计算。 我的代码的某些部分需要高精度,而对于大多数其他部分,则需要较低的精度。

我将默认精度设置为一个较低的数字,然后使用with来获得某些部分的更精确答案:

from decimal import localcontextwith localcontext() as ctx:ctx.prec = 42   # Perform a high precision calculations = calculate_something()
s = +s  # Round the final result back to the default precision

我在“超几何测试”中经常使用此功能,该测试需要将大量数字除以形式阶乘。 在进行基因组比例计算时,必须注意舍入和溢出错误。


#9楼

开箱即用支持的另一个示例是流行的数据库模块的connection对象,当您习惯于内置open()行为时,乍一看可能会感到困惑。

  • sqlite3
  • psycopg2
  • cx_oracle

connection对象是上下文管理器,因此可以在with-statement中直接使用,但是在使用上述说明时,请注意:

with-block完成后,无论有无异常, 连接都不会关闭 。 如果with-block异常结束,则事务将回滚,否则将提交事务。

这意味着程序员必须注意自己关闭连接,但允许获取连接,并在多个with-statements使用它,如psycopg2 docs中所示:

conn = psycopg2.connect(DSN)with conn:with conn.cursor() as curs:curs.execute(SQL1)with conn:with conn.cursor() as curs:curs.execute(SQL2)conn.close()

在上面的示例中,您会注意到psycopg2cursor对象也是上下文管理器。 从有关行为的相关文档中:

cursor退出with-block它会关闭,释放最终与之关联的任何资源。 交易状态不受影响。


#10楼

在python中,通常使用“ with ”语句来打开文件,处理文件中存在的数据,以及不调用close()方法而关闭文件。 “ with”语句通过提供清理活动使异常处理更加简单。

的一般形式:

with open(“file name”, “mode”) as file-var:processing statements

注意:无需通过在file-var.close()上调用close()来关闭文件

python“ with”语句的用途是什么?相关推荐

  1. python的用途-python“ with”语句的用途是什么?

    小编典典 我相信这已经在我之前的其他用户那里得到了回答,因此我仅出于完整性的考虑而添加:该with语句通过将通用的准备工作和清理任务封装在所谓的上下文管理器中来简化异常处理.可以在PEP 343中找到 ...

  2. python基础常用语句-Python基本语句

    在学习W3Cschool python高级教程之前,大家接触过许多python语句,在本文中我们将Python一些基本的常用语句做了汇总,并简单介绍下这些python常用语句的用途和标准格式,放在一起 ...

  3. python判断语句入门教程_Python中的条件判断语句基础学习教程

    if语句用来检验一个条件, 如果 条件为真,我们运行一块语句(称为 if-块 ), 否则 我们处理另外一块语句(称为 else-块 ). else 从句是可选的. 使用if语句: ? 输出: ? 在这 ...

  4. python注释语句不被解释器过滤掉、也不被执行_中华诗词之美超星2020年章节答案...

    某高原地区卫生站护士,采用煮沸法消毒患者使用过的餐具,计算消毒时间正确的是:海拔每增加300m.延长消毒时间 [填空题]ARM CORTEX M3/4微控制器是基于ARMv()版本指令集架构的. [单 ...

  5. 忘了python关键语句?这份备忘录拯救你的记忆

    忘了Python关键语句?这份备忘录拯救你的记忆 今天要介绍的 Python 3 Cheat Sheet 由法国国家科学研究中心(CNRS)的法国机械工程与信息技术实验室(LIMSI)的工程师 Lau ...

  6. 包教包会!7段代码带你玩转Python条件语句(附代码)

    来源:大数据 本文约5200字,建议阅读10分钟. 本文介绍了Python条件语句常用的7段代码. [ 导 读 ]条件语句通过一个或多个布尔表达式的执行结果(真值或假值)决定下一步的执行方向.所谓布尔 ...

  7. python入门语句_Python 快速入门笔记(5):语句

    本系列随笔是本人的学习笔记,初学阶段难免会有理解不当之处,错误之处恳请指正.转载请注明出处: https://www.cnblogs.com/itwhite/p/12297769.html. 简介 p ...

  8. python循环语句-Python-循环语句及循环控制语句

    循环语句允许我们执行一个语句或语句组多次,下面是在大多数编程语言中的循环语句的一般形式: Python 提供了 for 循环和 while 循环(在 Python 中没有 do..while 循环): ...

  9. python基本语法语句-Python基本语句

    一.Python 条件语句 Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. 可以通过下图来简单了解条件语句的执行过程: Python程序语言指定任何非 ...

最新文章

  1. android .9图片使用和一些技巧
  2. python怎么判断是不是列表_python判断变量是否为int、字符串、列表、元组、字典等方法...
  3. oracle 并接去掉字符串,ORACLE删除字符-TRIM字符截取-substr查找字符-instr
  4. php 类 init,基于initPHP的框架介绍
  5. JAVA--网络编程
  6. 用3年时间破解学界200多年难题,年仅21岁的天才竟因谈了一场恋爱挂掉了.........
  7. K近邻算法的kd树实现
  8. FPGA实现VGA显示(三)——————单个字符显示
  9. CUDA精进之路(三):图像处理——图像灰度化、灰度直方图统计
  10. 前端工程师---软必备
  11. 简单分布式系统构建知识
  12. C# 操作offfice权限问题
  13. delphi 剪切板变量_delphi读写剪贴板
  14. [转]Netlog 的数据库及 LAMP 架构
  15. C#,入门教程——列表(List)的基础知识
  16. 朱棣文 哈佛开学典礼演讲
  17. Kafka SASL/PLAIN 环境构建(Docker版)
  18. POI 实现Word替换文本2种情况(正常文本、表格文本)
  19. 极值理论(二):阈值超越量与尾部估计
  20. module.exports 与 exports.xxx 的区别

热门文章

  1. 面试常问 Java基础 冒泡排序
  2. 【Java基础】面向对象特性
  3. 第十二周项目二-Time类中的运算符重载
  4. 数据量大mysql当月_mysql 1.5倍数据量导致20多倍的执行时间?
  5. Spark读取Hive中的数据加载为DataFrame
  6. Vue Router路由及路由重定向
  7. 【Rollo的Python之路】Python 同步条件 学习笔记 Event
  8. 随手记——大整数运算模板(进化史)
  9. MyBatis基于注解的使用
  10. 以二进制的形式查看文件 Linux之od命令详解