有没有比使用全局变量从上下文管理器获取有趣值更好的方法?
@contextmanager
def transaction():
global successCount
global errorCount
try:
yield
except:
storage.store.rollback()
errorCount += 1
else:
storage.store.commit()
successCount += 1
Run Code Online (Sandbox Code Playgroud)
其他可能性:
有点全局...
使功能更加特定于问题/更少可重用
与元组相同的问题,但更清晰
真的很糟糕
有没有人在python的文件对象实现__enter__和__exit__用例之外有一个真实世界的例子?最好是你自己的,因为我想要实现的是一个更好的方法来概念化它将被使用的情况.
我已经读过了.
我正在为一个正在研究的项目提供几个上下文管理器.它即将发货,我遇到了一些我开始恐慌的事情.
我的印象是你不应该再加上作为上下文管理器类的__exit__方法的参数传递的异常.但是,我正在进行一些测试,看起来上下文管理器正在抑制一个被抛入其中的异常.当我将__exit__方法更改为如下所示时:
def __exit__(self, type_, value, trace):
if trace is not None:
print('ERROR IN TRACEBACK: ' + str(value))
# PYTHON 2.7 RAISE SYNTAX:
raise type_, value, trace
Run Code Online (Sandbox Code Playgroud)
这些错误似乎正确地通过了.
我的问题是:如果type_,value和trace不是None,那么在__exit__方法中处理异常的正确方法是什么?提升(重新加注?)这样的例外是不是很糟糕?这是我应该怎么做的?
我遇到的错误可能是由其他原因造成的.通常我会仔细检查这一切,但我的时间似乎非常有限.我希望有人可以解释这个功能的正确实现
最终:我可以在上下文管理器__exit__方法中安全地保留raise type_,value,trace吗?
使用with语句,我们可以只使用一个级别的缩进/嵌套来输入许多上下文处理程序:
>>> from contextlib import contextmanager
>>> @contextmanager
... def frobnicate(n):
... print('frobbing {}'.format(n))
... yield
...
>>> frob1 = frobnicate(1)
>>> frob2 = frobnicate(2)
>>> with frob1, frob2:
... pass
...
frobbing 1
frobbing 2
Run Code Online (Sandbox Code Playgroud)
但这似乎不起作用:
>>> frobs = [frobnicate(1), frobnicate(2)]
>>> with *frobs:
... pass
# SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)
我们如何输入n个上下文管理器而不必手动写出每个上下文管理器?
在 Python Lan 参考文献中。3.4.4,据说__aenter__()并且__aexit__()必须返回awaitables。但是,在示例异步上下文管理器中,这两个方法返回 None:
class AsyncContextManager:
async def __aenter__(self):
await log('entering context')
async def __aexit__(self, exc_type, exc, tb):
await log('exiting context')
Run Code Online (Sandbox Code Playgroud)
这段代码正确吗?
以下代码在withpython3的语句和异常处理上做错了什么吗?如果否,那么写期望输出的正确方法是什么?
from contextlib import contextmanager
@contextmanager
def test():
print("Hello")
yield
print("goodbye")
try:
with test():
print("inside test")
raise KeyError
except KeyError:
print("KeyError")
else:
print("else")
finally:
print("finally")
Run Code Online (Sandbox Code Playgroud)
输出是
Hello
inside test
KeyError
finally
Run Code Online (Sandbox Code Playgroud)
我希望输出是:
Hello
inside test
goodbye
KeyError
finally
Run Code Online (Sandbox Code Playgroud)
我相信其他人也会这样写,希望当文件处理过程中引发异常时将文件关闭。
我的python3版本是:
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> print(sys.version)
3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 …Run Code Online (Sandbox Code Playgroud) python exception-handling with-statement contextmanager python-3.x
我正在尝试在我的数据库框架中管理事务(我使用 MongoDB 和 umongo 而不是 pymongo)。
\n要使用事务,必须session沿整个调用链传递一个 kwarg。我想提供一个上下文管理器来隔离事务。只有调用链末尾的函数需要知道该session对象。
我发现了上下文变量,并且我已经接近一些东西,但还没有完全实现。
\n我想要什么:
\nwith Transaction():\n #\xc2\xa0Do stuff\n d = MyDocument.find_one()\n d.attr = 12\n d.commit()\nRun Code Online (Sandbox Code Playgroud)\n这是我现在想到的:
\ns = ContextVar(\'session\', default=None)\n\nclass Transaction(AbstractContextManager):\n\n def __init__(self):\n self.ctx = copy_context()\n # Create a new DB session\n session = db.create_session()\n # Set session in context\n self.ctx.run(s.set, session)\n\n def __exit__(self, *args, **kwargs):\n pass\n\n # Adding a run method for convenience\n def run(self, func, *args, **kwargs):\n self.ctx.run(func, *args, **kwargs)\n\ndef func():\n d …Run Code Online (Sandbox Code Playgroud) python contextmanager python-3.x python-3.7 python-contextvars
我想要一个在应用程序的生命周期内打开(输入?)的上下文管理器。它应该在模块加载时打开,并在模块销毁时关闭。
包装整个模块代码是行不通的,因为当模块加载完成时,上下文管理器将关闭,而当实际调用方法时,上下文管理器将不再打开。
import aiohttp
with context as c:
def f1():
c.do_something('one')
def f2():
c.do_something('two')
Run Code Online (Sandbox Code Playgroud)
具体来说,我想aiohttp.ClientSession为该模块创建一个,该模块可重用于多个不同的请求,并在应用程序停止时干净地关闭。为此使用上下文管理器是一个好主意还是有更好的方法?
我以为这样做
@f
def g():
print 'hello'
Run Code Online (Sandbox Code Playgroud)
与...完全相同
def g():
print 'hello'
g=f(g)
Run Code Online (Sandbox Code Playgroud)
但是,我有这个代码,它使用contextlib.contextmanager:
@contextlib.contextmanager
def f():
print 1
yield
print 2
with f:
print 3
Run Code Online (Sandbox Code Playgroud)
有效和收益 1 3 2
当我试图改变它
def f():
print 1
yield
print 2
f=contextlib.contextmanager(f)
with f:
print 3
Run Code Online (Sandbox Code Playgroud)
我明白了 AttributeError: 'function' object has no attribute '__exit__'
我错过了什么?在contextlib.contextmanager中是否有一些黑魔法,或者我是否误解了装饰器的工作原理?
我已经读过,每次使用'with'时都会调用对象的__ enter __()和__ exit __()方法.我理解,对于用户定义的对象,您可以自己定义这些方法,但我不明白它如何适用于内置对象/函数,如"open"甚至是测试用例.
此代码按预期工作,我假设它使用__ exit __()关闭文件:
with open('output.txt', 'w') as f:
f.write('Hi there!')
Run Code Online (Sandbox Code Playgroud)
要么
with self.assertRaises(ValueError):
remove_driver(self.driver) # self refers to a class that inherits from the default unittest.TestCase
Run Code Online (Sandbox Code Playgroud)
然而,当我检查它时,对任一对象都没有__ enter __()或__ exit __()方法:
那么'开放'如何与'同时'合作?不应该支持上下文管理协议的对象__输入__()和__ exit __()方法定义和检查吗?
contextmanager ×10
python ×10
python-3.x ×2
aiohttp ×1
asynchronous ×1
conceptual ×1
decorator ×1
python-2.7 ×1
python-3.7 ×1