我应该使用`import os.path`还是`import os`?
根据官方文档 , os.path
是一个模块。 那么,导入它的首选方式是什么?
# Should I always import it explicitly? import os.path
要么…
# Is importing os enough? import os
请不要回答“为我导入os
作品”。 我知道,它现在也适用于我(Python 2.6)。 我想知道的是关于这个问题的任何官方build议。 所以,如果你回答这个问题,请张贴你的参考 。
os.path
以一种有趣的方式工作。 它看起来像os
应该是一个具有子模块path
的包,但实际上os
是一个正常的模块,用sys.modules
来注入os.path
。 以下是发生的事情:
-
当Python启动时,它将一堆模块加载到
sys.modules
。 它们没有绑定到脚本中的任何名称,但是当您以某种方式导入它们时,您可以访问已经创build的模块。-
sys.modules
是一个模块caching的字典。 当你导入一个模块时,如果它已经被导入到某个地方,它将得到存储在sys.modules
的实例。
-
-
os
是Python启动时加载的模块之一。 它将其path
属性分配给特定于操作系统的path模块。 -
它注入
sys.modules['os.path'] = path
以便能够像import os.path
子模块那样执行“import os.path
”。
我倾向于把os.path
想象成一个我想要使用 的模块 ,而不是os
模块中的一个模块 ,所以即使它不是一个名为os
的包的子模块,我也可以导入它,就像它是一个, 我总是请import os.path
。 这与os.path
的logging是一致的。
顺便说一句,这种结构导致了很多Python程序员早就对模块,包和代码组织的困惑,我想。 这真的有两个原因
-
如果你认为
os
是一个包,并且知道你可以import os
并且可以访问子模块os.path
,那么当你不能import twisted
时候你可能会感到惊讶,并且不能import twisted
twisted.spread
。 -
令人困惑的是,
os.name
是一个正常的东西,一个string,os.path
是一个模块。 我总是用空的__init__.py
文件构build我的包,以便在同一级别上我总是有一种types的东西:一个模块/包或其他东西。 几个大型的Python项目采用这种方法,这往往使更多结构化的代码。
根据Tim Peters的PEP-20 ,“显式比隐式更好”和“可读性计数”。 如果你需要从os
模块获得os.path
,那么import os.path
将会更加明确,并让别人知道你真正关心的是什么。
同样,PEP-20也会说“简单比复杂”更好,所以如果你还需要更多一般的os
,那么import os
将是首选。
确定的答案: import os
并使用os.path
。 不要直接import os.path
。
从模块本身的文档:
>>> import os >>> help(os.path) ... Instead of importing this module directly, import os and refer to this module as os.path. The "os.path" name is an alias for this module on Posix systems; on other systems (eg Mac, Windows), os.path provides the same operations in a manner specific to that platform, and is an alias to another module (eg macpath, ntpath). ...
有趣的是,导入os.path将导入所有的操作系统。 在交互式提示符下尝试以下操作:
import os.path dir(os)
结果将与您刚刚导入的操作系统相同。 这是因为os.path会根据你拥有的操作系统来引用不同的模块,所以python会导入os来决定为哪个模块加载path。
参考
有一些模块,说import foo
不会暴露foo.bar
,所以我想这真的取决于具体模块的devise。
一般来说,只需导入你需要的显式模块应该稍微快一些。 在我的机器上:
import os.path
: 7.54285810068e-06
秒
import os
: 9.21904878972e-06
秒
这些时间非常接近,可以忽略不计。 你的程序可能需要使用os
其他模块,不pipe是现在还是之后,通常只需牺牲两微秒就可以使用import os
来避免这个错误。 我通常只是作为一个整体来导入操作系统,但可以看到为什么有些人会更喜欢import os.path
在技术上是更高效的,并向读者传达了这是os
模块中唯一需要使用的部分。 这在本质上归结为一个风格问题。
找不到任何明确的参考,但我看到os.walk的示例代码使用os.path,但只能导入os
我同意迈克
我认为
import os
是好的。
你只需要提到这样的细节
os.path()
或者如果您正在调用模块内的模块
os.path.exists()