简体   繁体   中英

How to use a context manager in python

Below is a hypothetical piece of code

with dbengine.connect(**details) as db:
    cur = db.exec(sql_string)
    results = cur.fetchall()
return results

In this case I would expect that when tabbed out of that with block db.close() is called and db is marked for garbage collection.

In work I've started seeing this code crop up.

with something() as myobj:
    logger.info('I got an obj!')
return myobj

I don't know if you should be using with like the new keyword in java. Could someone direct me to any good docs that might explain what you can/can't should/shouldn't do when using with?

PS Log messages are actually that lame :-)

The target name the with statement binds the contextmanager __enter__ return value to (the name after as ) is not scoped to just the with statement. Like for loop variable, the as target name is scoped in the current function or module namespace. The name does not disappear or is otherwise cleared when the with suite ends.

As such, return myobj outside of the with statement is perfectly legal, if somewhat nonsensical. All that the with statement guarantees is that the something().__exit__() method will have been called when the block completes (be that by reaching the end of the block, or because of a continue , break or return statement, or because an exception has been raised).

That said, you'd be better off just moving the return inside the with statement:

with something() as myobj:
    logger.info('I got an obj!')
    return myobj

and

with dbengine.connect(**details) as db:
    cur = db.exec(sql_string)
    return cur.fetchall()

The context manager will still be cleaned up properly, but now the return statement looks like it is a logical part of the with block. The execution order is not altered; something().__exit__() is called, then the function returns.

As always, the Python documentation on the with syntax is excellent. You could also review the documentation on context managers and the original proposal, PEP-343 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM