为什么可调用的内容在Python 3.5 with
语句中无法调用的任何押韵或原因?
class Seriously(object):
def __init__(self, name):
self.name = name
def __enter__(self):
print("Enter " + self.name)
def __call__(self):
print("Call " + self.name)
def __exit__(self, type, value, traceback):
print("Exit " + self.name)
a = Seriously('a')
a.__enter__()
a()
a.__enter__()
with Seriously('b') as b:
b()
认真生产
Enter a
Call a
Enter a
Enter b
Exit b
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-6-91a5d11e1b2e> in <module>()
18
19 with Seriously('b') as b:
---> 20 b()
TypeError: 'NoneType' object is not callable
我在PEP 343中遗漏了什么?
答案 0 :(得分:4)
您不会从__enter__
方法返回任何内容,该方法由python编译器转换为None
的返回值。您应该从as
返回__enter__
子句绑定的值。
with
语句被视为
mgr = (EXPR)
exit = type(mgr).__exit__
value = type(mgr).__enter__(mgr) ### <--- usually the same as mgr.__enter__()
exc = True
try:
try:
VAR = value ### <--- value returned by __enter__, VAR from with/as statement
BLOCK
except:
exc = False
if not exit(mgr, *sys.exc_info()):
raise
finally:
if exc:
exit(mgr, None, None, None)
(来自您在问题中链接的PEP)。
答案 1 :(得分:0)
__enter__
方法可以显式返回对象(self
),构造函数已在__enter__
之前调用。您可以直接传递对象或更改它或返回不同的对象。
__exit__
方法获取四个参数self
,后跟异常类型,值和回溯对象 - 与sys.exc_info()
返回的相同。如果没有异常,那么三个异常参数都是None
。
如果__exit__
返回True
,则表示该异常已被处理且未传播。返回值False
表示没有例外。