在运行时尝试修补上下文管理器时,我注意到以下代码的行为不像我预期的那样:
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虽然main的第一部分(对__enter__的显式调用)按预期运行(正确修改了方法),但with-statement似乎忽略了这一点。
经过一些搜索后,我发现an 佩普343显示了一个解释行为的示例翻译,即with mgr: ...的内部翻译使用了以下内容
type(mgr).__enter__(mgr)而不是直接的方法调用,就像我上面所做的那样。
我想知道为什么要这么做。是为了防止像我这样的人乱搞,还是有更深层次的原因?
发布于 2017-01-15 16:37:29
在语言描述中定义了一个叫做特殊方法查找的东西。基本上,这种查找(使用type(obj).__method__(obj))发生在所有“神奇方法”中;原因有两个:
int.__hash__与type(int).__hash__不同,这是我们通常真正想要的)。https://stackoverflow.com/questions/41663514
复制相似问题