手动打开上下文管理器
manually open context manager
我的问题是,如何在不使用 with
的情况下执行任何上下文管理器?
Python有上下文管理器的想法,
而不是
file = open('some_file', 'w')
try:
file.write('Hola!')
finally:
file.close()
# end try
你可以写
with open('some_file', 'w') as opened_file:
opened_file.write('Hola!')
# end with
虽然在大多数情况下,第二个是黄金解决方案,但为了在交互式控制台中进行测试和探索,第一个可以更好地使用,因为您可以逐行编写它。
>>> file = open('some_file', 'w')
>>> file.write('Hola!')
>>> file.close()
我的问题是,我怎样才能像这样执行最适合探索的任何 with
上下文管理器?
我的实际用例如下,但请尝试给出一个通用的答案,并且也适用于其他上下文管理器。
import flask
app = flask.Flask(__name__)
with app.test_request_context('/?name=Peter'):
assert flask.request.path == '/'
assert flask.request.args['name'] == 'Peter'
你可以调用app.test_request.context('/?name=Peter')
到一个变量(例如ctx
),然后在它上面调用ctx.__enter__()
进入上下文管理器,ctx.__exit__(None, None, None)
执行清理。请注意,您将失去上下文管理器的安全保证,除非您将 ctx.__exit__
放在 finally
子句中。
您仍然可以在交互式控制台中使用 with
语法,但是上下文基于 2 个魔术方法 __enter__
和 __exit__
,因此您可以只使用它们:
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")
通常你会这样做:
with MyCtx(foo) as f:
f()
同于:
ctx = MyCtx(foo)
f = ctx.__enter__()
f()
ctx.__exit__()
这里有 live example
记住上下文 __exit__
方法用于管理上下文中的错误,因此它们中的大多数都有 __exit__(exception_type, exception_value, traceback)
的签名,如果您不需要为测试处理它,只需给它有一些 None
值:
__exit__(None, None, None)
我的问题是,如何在不使用 with
的情况下执行任何上下文管理器?
Python有上下文管理器的想法,
而不是
file = open('some_file', 'w')
try:
file.write('Hola!')
finally:
file.close()
# end try
你可以写
with open('some_file', 'w') as opened_file:
opened_file.write('Hola!')
# end with
虽然在大多数情况下,第二个是黄金解决方案,但为了在交互式控制台中进行测试和探索,第一个可以更好地使用,因为您可以逐行编写它。
>>> file = open('some_file', 'w')
>>> file.write('Hola!')
>>> file.close()
我的问题是,我怎样才能像这样执行最适合探索的任何 with
上下文管理器?
我的实际用例如下,但请尝试给出一个通用的答案,并且也适用于其他上下文管理器。
import flask
app = flask.Flask(__name__)
with app.test_request_context('/?name=Peter'):
assert flask.request.path == '/'
assert flask.request.args['name'] == 'Peter'
你可以调用app.test_request.context('/?name=Peter')
到一个变量(例如ctx
),然后在它上面调用ctx.__enter__()
进入上下文管理器,ctx.__exit__(None, None, None)
执行清理。请注意,您将失去上下文管理器的安全保证,除非您将 ctx.__exit__
放在 finally
子句中。
您仍然可以在交互式控制台中使用 with
语法,但是上下文基于 2 个魔术方法 __enter__
和 __exit__
,因此您可以只使用它们:
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")
通常你会这样做:
with MyCtx(foo) as f:
f()
同于:
ctx = MyCtx(foo)
f = ctx.__enter__()
f()
ctx.__exit__()
这里有 live example
记住上下文 __exit__
方法用于管理上下文中的错误,因此它们中的大多数都有 __exit__(exception_type, exception_value, traceback)
的签名,如果您不需要为测试处理它,只需给它有一些 None
值:
__exit__(None, None, None)