在运行时尝试修补上下文管理器时,我注意到以下代码的行为与我预期的不同:
class B:
def __enter__(self):
print('normal')
def __exit__(self, *stuff):
pass
def modify(self, x):
def other(self):
print('not normal: ', x)
self.__enter__ = other.__get__(self, type(self))
def main():
b = B()
b.__enter__()
b.modify('hi')
b.__enter__()
with b:
print('in with')
b.__enter__()
if __name__ == '__main__':
main()
执行后,打印:
normal
not normal: hi
normal
in with
not normal: hi
虽然带有对__enter__
的显式调用的main
的第一部分的行为与预期的一样(方法被正确修改),但with
-语句似乎忽略了这一点。你知道吗
经过一番搜索,我发现相应的PEP 343显示了一个示例翻译,它解释了行为;即with mgr: ...
的翻译在内部使用了
type(mgr).__enter__(mgr)
而不是像上面那样直接调用方法。你知道吗
我想知道为什么会这样。只是为了防止像我这样的人胡闹,还是有更深层次的原因?你知道吗
在语言描述中定义了special method lookup。基本上,这种查找(使用
type(obj).__method__(obj)
)适用于所有“魔术方法”;给出了两个原因:int.__hash__
与type(int).__hash__
不同,这是我们通常真正想要的)相关问题 更多 >
编程相关推荐