我今天第一次遇到Python with语句。我已经简单地使用Python几个月了,甚至不知道它的存在!鉴于它的地位有些模糊,我认为有必要问一下:

Python with语句是什么 设计用于? 是什么 你用它干什么? 有吗? 我需要注意的问题,还是 相关联的常见反模式 它的使用?在什么情况下try. finally比with更好? 为什么它没有被更广泛地使用呢? 哪些标准库类与它兼容?


当前回答

另一个开箱即用支持的例子是流行数据库模块的连接对象,例如:

sqlite3 psycopg2 cx_oracle

连接对象是上下文管理器,因此可以在with-statement中开箱即用,但是在使用上述方法时请注意:

当with-block结束时,无论是否出现异常,连接都不会关闭。如果with-block以异常结束,则事务将回滚,否则事务将被提交。

这意味着程序员必须小心自己关闭连接,但允许获取一个连接,并在多个with-语句中使用它,如psycopg2文档所示:

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()

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

当游标退出with-block时,游标将被关闭,释放与游标最终关联的所有资源。事务的状态不会受到影响。

其他回答

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

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

这个想法是通过在离开with块后进行必要的清理来简化异常处理。一些python内置程序已经作为上下文管理器工作。

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

... 新的语句"with"到Python 制造语言 可以排除try/finally语句的标准用法。

反模式的一个例子可能是在循环内部使用with,而在循环外部使用with会更有效

例如

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

vs

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

第一种方法是为每一行打开和关闭文件,与第二种只打开和关闭一次文件的方法相比,这可能会导致性能问题。

第1点、第2点和第3点得到了很好的阐述:

4:它相对较新,仅在python2.6+中可用(或python2.5使用from __future__ import with_statement)

在python中,通常使用" with "语句打开文件,处理文件中的数据,并在不调用close()方法的情况下关闭文件。" with "语句通过提供清理活动简化了异常处理。

with的一般形式:

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

注意:不需要在file_var.close()上调用close()来关闭文件