os.path
以一种有趣的方式工作。看起来os
应该是一个带有子模块的程序包path
,但实际上os
是一个普通的模块,sys.modules
可以注入魔力os.path
。这是发生了什么:
Python启动时,会将一堆模块加载到中sys.modules
。它们没有绑定到脚本中的任何名称,但是以某种方式导入它们时,您可以访问已创建的模块。
它会注入,sys.modules['os.path'] = path
以便您可以像对待import os.path
子模块一样执行“ ”。
我倾向于将其os.path
看作 是我要使用 的os
模块,而不是 模块中的 任何东西 ,因此,即使它 实际上 不是被称为包的子模块os
,我也可以将其导入,就像 。这与os.path
记录方式一致。
顺便说一句,我认为这种结构导致很多Python程序员对模块和包以及代码组织产生了早期的困惑。这确实有两个原因
如果您将其os
视为一个包并且知道可以执行import os
并有权访问该子模块os.path
,则稍后可能会感到惊讶,因为您无法执行import twisted
并且twisted.spread
无需导入就可以自动访问。
令人困惑的是,这os.name
是正常现象,字符串和os.path
模块。我总是用空__init__.py
文件来构造我的包,以便在同一级别上我总是有一种类型的东西:模块/包或其他东西。几个大型的Python项目都采用这种方法,这往往会使代码更加结构化。