Python中模块变量__path__在这段代码中咋传进来的

大概是需要判断一下你from的这个变量究竟是个package还是个module吧,如果是个package,逻辑和module的情况略有不同。判断的方法似乎用到了__path__。具体可以查一下相关的源代码。

■网友
既然小权权都问了,正好今下午有点时间,那就答一下吧。:-D

先看bluesprint_factory.py的代码做了什么事情:
定义了一个 Wrapper 类;定义了一个 AutoBlueprint 类;把 bluesprint_factory 模块做了一次封装并替换。
再详细看上述第3步做了什么事:
【Python中模块变量__path__在这段代码中咋传进来的】 sys.modules = Wrapper(sys.modules)
先从 sys.modules 中得到代表当前py模块被解析后的module对象,先称之为origin_module;将origin_module对象传递给Wrapper类,得到一个wrapper 对象,称之为wrapped_module,该对象只具有一个属性self.wrapped,其值为origin_module ;再把wrapped_module对象绑定给 sys.modules 这个变量。总之,经过最后一行代码的执行后:
sys.modules = wrapped_module wrapped_module.wrapped = orign_module 到此为止,bluesprint_factory.py 的初始化工作就完成了。

最后,再看从别的模块 from bluesprint_factory import bl会发生什么:
当执行 from x import y 的时候,Python 需要先判断 x 是否为package,而判断条件就是 x 是否具有 __path__属性 ,不论__path__的值如何。;尝试访问 bluesprint_factory 模块对象——wrapped_module ——的__path__属性;由于wrapped_module被实例化之后,并无__path__ 属性,进入 wrapped_module.__getattr__() ;此处就是你要的答案,为何 __getattr__ 拦截到了"__path__" ,因为 Python 的 import 机制去尝试访问了这个实例化后并不存在的属性;wrapped_module.__getattr__() 中的 if 判断第一次显然会失败,然后走到 return getattr(self.wrapped, key) ,等价于 return getattr(orign_module, \u0026#39;__path__\u0026#39;) ;明显,上一步 return 之后的控制权限又回到了 Python 的 import 机制中,而且它得到None ,因为 orign_module 并非package,没有 \u0026#39;__path__\u0026#39;属性;此时,import 机制知道了 from bluesprint_factory中的 bluesprint_factory就是一个正常的module,而非package,然后尝试从 bluesprint_factory 这个module 中获取bl属性;接着需要拿到 bluesprint_factory的 module 对象,此时拿到的是 wrapped_module,因为你已经把sys.modules里的那个对象给替换了; 然后相当于要取得 wrapped_module.bl,同理,bl在初始化时并不存在,于是进入 wrapped_module.__getattr__()此时的key,已经成了\u0026#39;bl\u0026#39; ;于是 if key == \u0026#39;bl\u0026#39; 条件成立,调用AutoBlueprint 类创建其实例。后续AutoBlueprint 里的操作就不用再解释了吧。
经过上述解释后,应该可以知道,除了


推荐阅读