理解python3嵌套上下文管理器

问题描述 投票:1回答:1

我有一节课:

class OuterCtxManager:
  def __enter__(self): 
    print('Outer enter')
  def __exit__(self, exc_type, exc_val, exc_tb):
    print('Outer exit')

当我这样做:

def test_func():
  return OuterCtxManager()

with test_func() as context_manager:
  print('context_manager')

它打印:

Outer enter
context_manager
Outer exit

尽管在函数中已经创建的对象上使用了上下文管理器,为什么它会打印Outer enterOuter exit? (而不是在创建像with OuterCtxManager() as ocm这样的对象时直接使用)

有趣的事情接下来:

当我做:

def test_func():
  first_object = OuterCtxManager()
  second_object = OuterCtxManager()
  return [first_object, second_object]

with test_func() as context_manager:
  print('context_manager')

它提出:

AttributeError:输入

最后,当我这样做时:

class OuterCtxManager:
  def __init__(self):
    self.inner_ctx = InnerCtxManager()
  def __enter__(self): 
    print('Outer enter')
  def __exit__(self, exc_type, exc_val, exc_tb):
    print('Outer exit')

class InnerCtxManager:
  def __init__(self):
    print('inner_created')
  def __enter__(self): 
    print('Inner enter')
  def __exit__(self, exc_type, exc_val, exc_tb):
    print('Inner exit')


def test_func():
  first_object = OuterCtxManager()
  return first_object

with test_func() as context_manager:
  print('context_manager')

它打印:

inner_created
Outer enter
context_manager
Outer exit

我没有得到任何错误。我都没有得到Inner createdInner enter。为什么会这样?

Sandbox

python-3.x nested contextmanager
1个回答
0
投票

尽管在函数中已经创建的对象上使用了上下文管理器,为什么还要打印外部进入和外部出口?

你定义的with语句说python应该在执行__enter__语句的内容之前调用with,之后调用__exit__

对象是否已经初始化并不重要。无论如何,with语句将调用__enter____exit__

它提出了AttributeError: enter

当你返回一个元组并且元组不包含__enter__的定义时会抛出此错误。

我没有得到任何错误。我没有得到内在创造和内在进入。为什么会这样?

你没有得到任何错误,因为你正确地使用with语句和你的OuterCtxManager并且你没有得到输出Inner enterInner exit,因为你没有在with类型上使用InnerCtxManager语句。

© www.soinside.com 2019 - 2024. All rights reserved.