问题
My question is, how can I execute any context manager without using with
?
Python has the idea of context managers,
instead of
file = open('some_file', 'w')
try:
file.write('Hola!')
finally:
file.close()
# end try
you can write
with open('some_file', 'w') as opened_file:
opened_file.write('Hola!')
# end with
While in most cases the second one is the golden solution, for testing and exploring in the interactive console, the first one can be much better used, as you can write it line by line.
>>> file = open('some_file', 'w')
>>> file.write('Hola!')
>>> file.close()
My question is, how can I execute any with
context manager like this, best suited for exploring?
My actual use case follows below, but please try to give a answer which is generic and will work for other context managers too.
import flask
app = flask.Flask(__name__)
with app.test_request_context('/?name=Peter'):
assert flask.request.path == '/'
assert flask.request.args['name'] == 'Peter'
from flask docs
回答1:
You can still use with
syntax in the interactive console, however a context is based on 2 magic methods __enter__
and __exit__
, so you can just use them:
class MyCtx(object):
def __init__(self, f):
self.f = f
def __enter__(self):
print("Enter")
return self.f
def __exit__(*args, **kwargs):
print("Exit")
def foo():
print("Hello")
usually you do:
with MyCtx(foo) as f:
f()
Same as:
ctx = MyCtx(foo)
f = ctx.__enter__()
f()
ctx.__exit__()
Here you have the live example
Remember that contexts __exit__
method are used for managing errors within the context, so most of them have a signature of __exit__(exception_type, exception_value, traceback)
, if you dont need to handle it for the tests, just give it some None
values:
__exit__(None, None, None)
回答2:
You can call app.test_request.context('/?name=Peter')
to a variable (e.g. ctx
), and then call ctx.__enter__()
on it to enter the context manager, and ctx.__exit__(None, None, None)
to perform the cleanup. Note that you lose the safety guarantees of context managers, unless you put the ctx.__exit__
in a finally
clause.
来源:https://stackoverflow.com/questions/51706836/manually-open-context-manager