我今天第一次遇到Python with语句。我已经简单地使用Python几个月了,甚至不知道它的存在!鉴于它的地位有些模糊,我认为有必要问一下:
Python with语句是什么 设计用于? 是什么 你用它干什么? 有吗? 我需要注意的问题,还是 相关联的常见反模式 它的使用?在什么情况下try. finally比with更好? 为什么它没有被更广泛地使用呢? 哪些标准库类与它兼容?
我今天第一次遇到Python with语句。我已经简单地使用Python几个月了,甚至不知道它的存在!鉴于它的地位有些模糊,我认为有必要问一下:
Python with语句是什么 设计用于? 是什么 你用它干什么? 有吗? 我需要注意的问题,还是 相关联的常见反模式 它的使用?在什么情况下try. finally比with更好? 为什么它没有被更广泛地使用呢? 哪些标准库类与它兼容?
当前回答
参见PEP 343 - 'with'语句,末尾有一个示例部分。
... 新的语句"with"到Python 制造语言 可以排除try/finally语句的标准用法。
其他回答
第1点、第2点和第3点得到了很好的阐述:
4:它相对较新,仅在python2.6+中可用(或python2.5使用from __future__ import with_statement)
另一个开箱即用支持的例子是流行数据库模块的连接对象,例如:
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,而在循环外部使用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)
第一种方法是为每一行打开和关闭文件,与第二种只打开和关闭一次文件的方法相比,这可能会导致性能问题。
我想推荐两堂有趣的课:
PEP 343 with语句 Effbot理解Python的 ”与“声明
1. with语句用于用上下文管理器定义的方法包装块的执行。这允许普通的尝试…最后对使用模式进行封装,以方便重用。
2. 你可以这样做:
with open("foo.txt") as foo_file:
data = foo_file.read()
OR
from contextlib import nested
with nested(A(), B(), C()) as (X, Y, Z):
do_something()
OR (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))
OR
lock = threading.Lock()
with lock:
# Critical section of code
3. 我在这里没有看到任何反模式。 深入了解Python:
试一试,终于好了。有更好。
4. 我想这与程序员使用try..catch..的习惯有关。最后是来自其他语言的语句。
这里的答案很棒,但我只想补充一个帮助我的简单答案:
with open("foo.txt") as file:
data = file.read()
Open返回一个文件 自2.6以来,python在文件中添加了__enter__和__exit__方法。 With类似于一个for循环,调用__enter__,运行一次循环,然后调用__exit__ With作用于任何具有__enter__和__exit__的实例
在__exit__关闭文件之前,文件是锁定的,不能被其他进程重用。
来源:http://web.archive.org/web/20180310054708/http: / / effbot.org/zone/python-with-statement.htm