你不能做你想做的事,至少不能直接做。
你的
Indenter.__enter__
返回
Indenter
with indent:
使用那个
压头
对象作为上下文管理器,这很好,因为它是一个。
indenter
函数产生
压头
缩进:
使用那个
压头
对象作为上下文管理器失败,因为它不是上下文管理器。
你需要改变一些事情,这样你的回报就不会是
压头
压头
如果您愿意稍微更改API,可以执行以下操作:
@contextmanager
def indenter():
level=0
@contextmanager
def _indenter():
nonlocal level
try:
level += 1
yield
finally:
level -= 1
def _print(text):
print('\t' * level + text)
_indenter.print = _print
yield _indenter
压头
不创建上下文管理器,但它确实创建了返回上下文管理器的函数。这是内在的
@contextmanager
with indenter() as indent:
,不是
with indenter as indent:
,你必须这样做
with indent():
,不是
with indent
.
level
结束了。然后我们可以
contextmanager
它和钉
print
方法打开。现在:
>>> with indenter() as indent:
... indent.print('hi!')
... with indent():
... indent.print('hello')
... with indent():
... indent.print('bonjour')
... indent.print('hey')
hi!
hello
bonjour
hey
如果你想知道为什么我们不能
yield _indenter()
(好吧,我们得打电话
_indenter()
,然后在
然后就结果了
yield
但这不是主要问题),问题是
上下文管理器
contextlib
资料来源,你可以看到你怎么写
相反,它会产生一个函数,它将永远产生交替的输入和出口,并给您一个上下文管理器。
next
为每个人
__enter__
和
__exit__
__进入__
而不是开着
__init__
所以它可以
_recreate_cm
如果你对更多感兴趣,你应该去看看
contextlib2
,由Nick Coghlan和stdlib的其他作者编写的第三方模块
. 这两个都是用来移植的
上下文库
这是可重用的,但删除了它,因为一个错误,不能工作周围干净。