What is the python “with” statement designed for?
今天我第一次看到python
我相信我之前的其他用户已经回答了这个问题,所以我添加它只是为了完整性:
例如:使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 |
下面是另一个例子,它临时将
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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" |
最后,另一个创建临时文件夹并在离开上下文时将其清除的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 |
我建议两个有趣的讲座:
- PEP 343"with"声明
- effbot了解python的"with"语句
1。
2。你可以这样做:
1 2 | with open("foo.txt") as foo_file: data = foo_file.read() |
或
1 2 3 | from contextlib import nested with nested(A(), B(), C()) as (X, Y, Z): do_something() |
或(Python 3.1)
1 2 3 | with open('data') as input_file, open('result', 'w') as output_file: for line in input_file: output_file.write(parse(line)) |
或
1 2 3 | lock = threading.Lock() with lock: # Critical section of code |
三。我在这里看不到任何反模式。引用Python的话:
try..finally is good. with is better.
4。我想这和程序员使用其他语言的
Python EDCOX1×0语句是对C++中常用的EDCOX1·20的习惯用语的内置语言支持。它旨在允许安全获取和释放操作系统资源。
python库中的许多资源都遵守
每当您获取应用程序中必须明确放弃的资源(如文件、网络连接、锁等)时,都可以使用它。
为了完整起见,我将为
我做了很多科学计算,对于某些活动,我需要
我将默认精度设置为一个较低的数字,然后使用
1 2 3 4 5 6 | from decimal import localcontext with localcontext() as ctx: ctx.prec = 42 # Perform a high precision calculation s = calculate_something() s = +s # Round the final result back to the default precision |
我经常在超几何测试中使用这个方法,它要求将产生阶乘的大数除法。当你做基因组尺度计算时,你必须小心四舍五入和溢出错误。
反模式的一个例子可能是在循环内部使用
例如
1 2 3 | for row in lines: with open("outfile","a") as f: f.write(row) |
VS
1 2 3 | with open("outfile","a") as f: for row in lines: f.write(row) |
第一种方法是为每个
参见PEP 343-"with"语句,结尾有一个示例部分。
... new statement"with" to the Python
language to make
it possible to factor out standard uses of try/finally statements.
第1点、第2点和第3点被合理地涵盖:
4:比较新,只在python2.6+中提供(或使用
WITH语句与所谓的上下文管理器一起工作:
http://docs.python.org/release/2.5.2/lib/typecontextmanager.html
其思想是在离开"with"块后进行必要的清理,从而简化异常处理。一些python内置模块已经作为上下文管理器工作。
在python中,通常使用"with"语句来打开文件、处理文件中存在的数据,以及在不调用close()方法的情况下关闭文件。"with"语句通过提供清理活动使异常处理更简单。
一般形式:
1 2 | with open("file name","mode") as file-var: processing statements |
注意:不需要通过对file-var.close()调用close()来关闭文件。
另一个现成支持的例子是
- 平方英寸3
- PycPcG2
- CXI甲骨文
When the
with-block is finished, either with an exception or without, the connection is not closed. In case thewith-block finishes with an exception, the transaction is rolled back, otherwise the transaction is commited.
这意味着程序员必须注意自己关闭连接,但允许获取连接,并在多个
1 2 3 4 5 6 7 8 9 10 11 | 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() |
在上面的示例中,您将注意到
When a
cursor exits thewith-block it is closed, releasing any resource eventually associated with it. The state of the transaction is not affected.