Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 了解python3嵌套上下文管理器_Python 3.x_Nested_Contextmanager - Fatal编程技术网

Python 3.x 了解python3嵌套上下文管理器

Python 3.x 了解python3嵌套上下文管理器,python-3.x,nested,contextmanager,Python 3.x,Nested,Contextmanager,我有一门课: 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

我有一门课:

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')
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')
它打印:

Outer enter
context_manager
Outer exit
inner_created
Outer enter
context_manager
Outer exit
尽管在函数中已创建的对象上使用了上下文管理器,但为什么它仍然打印
Outer enter
Outer exit
?(而不是在创建像
这样的对象时直接使用OuterCtxManager()作为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:输入

最后,当我这么做的时候:

def test_func():
  return OuterCtxManager()

with test_func() as context_manager:
  print('context_manager')
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')
它打印:

Outer enter
context_manager
Outer exit
inner_created
Outer enter
context_manager
Outer exit
我没有发现任何错误。我既没有得到
内部创建的
内部输入
。为什么会这样


尽管在函数中已创建的对象上使用了上下文管理器,但为什么它仍然打印外部输入和外部输出

您定义的
with
语句表示,python应该在执行
with
语句的内容之前调用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
,然后调用
退出

不管对象是否已初始化。with语句无论如何都要调用
\uuuuuuuuuuuuuuuuuuuuuu
\uuuuuuuuuuuuuuuuuuuuu

它将引发
AttributeError:enter

返回元组时,如果元组不包含
\uuuuu enter\uuuu
的定义,则会引发此错误

我没有发现任何错误。我既没有得到内心的创造,也没有内心的进入。为什么会这样


您不会得到任何错误,因为您将
with
语句正确地用于
外部CtxManager
,并且不会得到输出
内部enter
内部exit
,因为您没有在
内部CtxManager
类型上使用
with
语句。

为什么它会打印外部enter和外部enter是否在函数中已创建的对象上使用上下文管理器仍要退出?(例如,不同于将OuterCtxManager()作为ocm的
)@trthhrtz基本上不管对象是否已初始化。
with
语句将调用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu