Python的with exp() as obj:
语法对任何具有强制性'的对象都很有吸引力。进入和退出方法 - 考虑到人们尝试延长obj.__del__
但结果不佳的情况,这似乎指向使用__enter__
和__exit__
方法的方法。
我想到的第一件事是具有进入和退出方法的状态机;无论如何都要处理的事情,但使状态机的实际实现变得非常简单。
class State(object):
def __init__(self, strategy):
self.strategy = strategy
def __enter__(self, *args):
return self
def __call__(self, *args, **kwargs):
self.strategy(self, *args, **kwargs)
def __exit__(self, *args):
clean_up_things()
...
...
...
def state_handle():
states = (State(foo), State(bar), State(eggs))
for state in states:
with state() as s:
what_ever(s)
然而,似乎人们通常会将with XXX as YYY
语法视为try/finally
子句和/或yield
语句的替代,我不断发现的一件事是Python社区喜欢知道实现某个功能时会发生什么。因此,如果使用错误的法术来解决正确的问题,那么它仍然是错误的答案。
由于特定原因,Python是否故意为生成器保留with...as
语法,或者可以按照人们认为合适的方式应用此语法?如果有目的,那么目的是什么? (我在PEP 8中看到了很少甚至没有提到with/as
,如果这样的话甚至是正确的地方)
答案 0 :(得分:1)
你似乎误解了一些东西。
[我]似乎通常会将XXX视为YYY语法,以替换try / finally子句和/或yield语句
不,一个人没有。无论何时需要管理上下文,都可以使用上下文管理器。你的用例很好。
使用上下文管理器替换try
.. finally
使用一个用例。我不确定你从哪里得到关于发电机的想法;也许是因为有用的@contextlib.contextmanager()
decorator允许您将生成器转换为上下文管理器,从而简化了创建上下文管理器的过程。
我可以想到Python标准库中至少有两个反例:
unittest
;使用assertRaises
作为上下文管理器可以引发异常,然后测试异常的各个方面。
decimal
; localcontext
管理十进制数精度,舍入和其他方面。
这些不是try
.. finally
处理程序的替代品,但您可以设想decimal
上下文与try
相同的功能。{{1}和一个增加的线程安全层;然而,这将是一项更多的工作。
最初的Python增强建议可能会让您感兴趣:http://www.python.org/dev/peps/pep-0343/