我有一节课:
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 enter
和Outer 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 created
和Inner enter
。为什么会这样?
尽管在函数中已经创建的对象上使用了上下文管理器,为什么还要打印外部进入和外部出口?
你定义的with
语句说python应该在执行__enter__
语句的内容之前调用with
,之后调用__exit__
。
对象是否已经初始化并不重要。无论如何,with语句将调用__enter__
和__exit__
它提出了
AttributeError: enter
当你返回一个元组并且元组不包含__enter__
的定义时会抛出此错误。
我没有得到任何错误。我没有得到内在创造和内在进入。为什么会这样?
你没有得到任何错误,因为你正确地使用with
语句和你的OuterCtxManager
并且你没有得到输出Inner enter
和Inner exit
,因为你没有在with
类型上使用InnerCtxManager
语句。