python - 在“with”语句中调用构造函数
问题描述
我有以下代码:
class Test:
def __init__(self, name):
self.name = name
def __enter__(self):
print(f'entering {self.name}')
def __exit__(self, exctype, excinst, exctb) -> bool:
print(f'exiting {self.name}')
return True
with Test('first') as test:
print(f'in {test.name}')
test = Test('second')
with test:
print(f'in {test.name}')
运行它会产生以下输出:
entering first
exiting first
entering second
in second
exiting second
但我预计它会产生:
entering first
in first
exiting first
entering second
in second
exiting second
为什么不调用我的第一个示例中的代码?
解决方案
该__enter__
方法应返回上下文对象。with ... as ...
使用的返回值__enter__
来确定给你什么对象。由于您__enter__
没有返回任何内容,因此它隐式返回None
,test
因此None
.
with Test('first') as test:
print(f'in {test.name}')
test = Test('second')
with test:
print(f'in {test.name}')
也没有test
。然后test.name
是错误。该错误被引发,因此Test('first').__exit__
被调用。__exit__
return True
,这表明错误已被处理(本质上,你__exit__
的行为就像一个except
块),所以代码在第一个with
块之后继续,因为你告诉 Python 一切都很好。
考虑
def __enter__(self):
print(f'entering {self.name}')
return self
你也可以考虑不返回True
,__exit__
除非你真的打算无条件地抑制块中的所有错误(并完全理解抑制其他程序员的错误的后果,以及KeyboardInterrupt
,StopIteration
和各种系统信号)
推荐阅读
- c# - System.Data.SqlClient.SqlException: '无效的列名'"
- java - MS SQL Server 域授权因 JDBC 失败
- php - \n 使用 chrome 浏览器时不能在 php 代码中工作
- dimensions - R dim 参数说明
- dart - 如何将 Iconbutton 单击后更改为不同的 Iconbutton
- c# - unity:围绕两个Vector3的中心旋转一个网格
- linear-programming - CVRP 无需访问每个节点
- python - 如何在 Postgres 数据库中保存会话?
- json - 如何从 KeyValue 管道中过滤特定值以显示在 html 表中的特定标题下 | 角 6 +
- java - 无注射器的guice注射