为何Python模块的__getattr__在from X import Y时被调用两次?
关于模块
__getattr__被重复调用的原因 你遇到的这个现象,本质是Python导入系统的两个核心逻辑导致的:
包属性检查触发的调用
Python在加载模块时,会先判断当前模块是否是一个包——包必须包含__path__属性。因为你的file_b.py里没有定义这个属性,所以导入时会调用__getattr__('__path__'),这就是输出里第一条记录的由来。导入过程的两次名称验证
当执行from file_b import foo, bar时,导入系统会经历两次名称查找:- 第一次:解释器先在模块的内置字典
__dict__里查找foo和bar,找不到就通过__getattr__获取,对应输出里的前两次foo、bar调用。 - 第二次:在把这两个名称绑定到
file_a的命名空间之前,导入系统会再次校验这些名称的有效性。由于你的模块通过__getattr__动态提供属性,解释器会再次调用它来确认名称可访问,于是又触发了一次foo和bar的调用。
- 第一次:解释器先在模块的内置字典
简单来说,就是导入流程里的两次校验逻辑,加上包属性的检查,共同导致了你看到的多次调用输出。
内容的提问来源于stack exchange,提问作者S.B
相关产品推荐
相关产品推荐

