What is the python “with” statement designed for?

后端 未结 10 1735
心在旅途
心在旅途 2020-11-21 07:52

I came across the Python with statement for the first time today. I\'ve been using Python lightly for several months and didn\'t even know of its existence! G

相关标签:
10条回答
  • 2020-11-21 07:54

    The Python with statement is built-in language support of the Resource Acquisition Is Initialization idiom commonly used in C++. It is intended to allow safe acquisition and release of operating system resources.

    The with statement creates resources within a scope/block. You write your code using the resources within the block. When the block exits the resources are cleanly released regardless of the outcome of the code in the block (that is whether the block exits normally or because of an exception).

    Many resources in the Python library that obey the protocol required by the with statement and so can used with it out-of-the-box. However anyone can make resources that can be used in a with statement by implementing the well documented protocol: PEP 0343

    Use it whenever you acquire resources in your application that must be explicitly relinquished such as files, network connections, locks and the like.

    0 讨论(0)
  • 2020-11-21 07:54

    points 1, 2, and 3 being reasonably well covered:

    4: it is relatively new, only available in python2.6+ (or python2.5 using from __future__ import with_statement)

    0 讨论(0)
  • 2020-11-21 07:57

    I would suggest two interesting lectures:

    • PEP 343 The "with" Statement
    • Effbot Understanding Python's "with" statement

    1. The with statement is used to wrap the execution of a block with methods defined by a context manager. This allows common try...except...finally usage patterns to be encapsulated for convenient reuse.

    2. You could do something like:

    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. I don't see any Antipattern here.
    Quoting Dive into Python:

    try..finally is good. with is better.

    4. I guess it's related to programmers's habit to use try..catch..finally statement from other languages.

    0 讨论(0)
  • 2020-11-21 07:59

    Another example for out-of-the-box support, and one that might be a bit baffling at first when you are used to the way built-in open() behaves, are connection objects of popular database modules such as:

    • sqlite3
    • psycopg2
    • cx_oracle

    The connection objects are context managers and as such can be used out-of-the-box in a with-statement, however when using the above note that:

    When the with-block is finished, either with an exception or without, the connection is not closed. In case the with-block finishes with an exception, the transaction is rolled back, otherwise the transaction is commited.

    This means that the programmer has to take care to close the connection themselves, but allows to acquire a connection, and use it in multiple with-statements, as shown in the 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()
    

    In the example above, you'll note that the cursor objects of psycopg2 also are context managers. From the relevant documentation on the behavior:

    When a cursor exits the with-block it is closed, releasing any resource eventually associated with it. The state of the transaction is not affected.

    0 讨论(0)
  • 2020-11-21 08:02

    See PEP 343 - The 'with' statement, there is an example section at the end.

    ... new statement "with" to the Python language to make it possible to factor out standard uses of try/finally statements.

    0 讨论(0)
  • 2020-11-21 08:03

    The with statement works with so-called context managers:

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

    The idea is to simplify exception handling by doing the necessary cleanup after leaving the 'with' block. Some of the python built-ins already work as context managers.

    0 讨论(0)
提交回复
热议问题