为什么'with'use'输入的是类的,而不是对象的?

2024-04-25 01:05:43 发布

您现在位置:Python中文网/ 问答频道 /正文

在运行时尝试修补上下文管理器时,我注意到以下代码的行为与我预期的不同:

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)

而不是像上面那样直接调用方法。你知道吗

我想知道为什么会这样。只是为了防止像我这样的人胡闹,还是有更深层次的原因?你知道吗


Tags: 方法inselfmaindeftypewithnot
1条回答
网友
1楼 · 发布于 2024-04-25 01:05:43

在语言描述中定义了special method lookup。基本上,这种查找(使用type(obj).__method__(obj))适用于所有“魔术方法”;给出了两个原因:

  • 性能优化是可能的
  • 有些情况下,只有使用此变体才能正确工作,即当特殊查找遵循类型时(例如,int.__hash__type(int).__hash__不同,这是我们通常真正想要的)

相关问题 更多 >