根据官方文档,os.path
是一个模块。因此,导入它的首选方式是什么?
# Should I always import it explicitly?
import os.path
或者...
# Is importing os enough?
import os
请不要回答“os
为我导入作品”。我知道,它现在也适用于我(从 Python 2.6 开始)。我想知道的是关于这个问题的任何官方建议。所以,如果你回答了这个问题,请张贴你的参考资料。
根据官方文档,os.path
是一个模块。因此,导入它的首选方式是什么?
# Should I always import it explicitly?
import os.path
或者...
# Is importing os enough?
import os
请不要回答“os
为我导入作品”。我知道,它现在也适用于我(从 Python 2.6 开始)。我想知道的是关于这个问题的任何官方建议。所以,如果你回答了这个问题,请张贴你的参考资料。
os.path
以一种有趣的方式工作。看起来os
应该是一个带有子模块的包path
,但实际上是一个普通的模块,可以用来注入os
魔法。这是发生的事情:sys.modules
os.path
当 Python 启动时,它会将一堆模块加载到sys.modules
. 它们不绑定到脚本中的任何名称,但是当您以某种方式导入它们时,您可以访问已经创建的模块。
sys.modules
是缓存模块的字典。当你导入一个模块时,如果它已经被导入到某个地方,它会获取存储在sys.modules
.os
是 Python 启动时加载的模块之一。它将其path
属性分配给特定于操作系统的路径模块。
它注入sys.modules['os.path'] = path
以便您能够执行“ import os.path
”,就好像它是一个子模块一样。
我倾向于将其os.path
视为我想要使用的模块,而不是模块中的一个东西os
,因此即使它不是一个名为的包的真正os
子模块,我也将它导入有点像它是一个并且我总是这样做import os.path
。这与os.path
记录的方式一致。
顺便说一句,我认为这种结构导致许多 Python 程序员早期对模块和包以及代码组织感到困惑。这真的有两个原因
如果您将其os
视为一个包并且知道您可以执行import os
并且可以访问 submodule os.path
,那么稍后您可能会感到惊讶,因为您无法执行并且无需导入即可import twisted
自动访问。twisted.spread
令人困惑的是,这os.name
是一个正常的东西,一个字符串,os.path
一个模块。我总是用空__init__.py
文件来构建我的包,这样在同一级别我总是有一种类型的东西:模块/包或其他东西。几个大型 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 (e.g. Mac, Windows),
os.path provides the same operations in a manner specific to that
platform, and is an alias to another module (e.g. macpath, ntpath).
...
有趣的是,导入 os.path 将导入所有的 os。在交互式提示中尝试以下操作:
import os.path
dir(os)
结果将与您刚刚导入 os. 这是因为 os.path 将根据您拥有的操作系统引用不同的模块,因此 python 将导入 os 以确定要为路径加载哪个模块。
有了一些模块,说import foo
不会暴露foo.bar
,所以我想这真的取决于具体模块的设计。
通常,仅导入所需的显式模块应该会稍微快一些。在我的机器上:
import os.path
: 7.54285810068e-06
秒
import os
: 9.21904878972e-06
秒
这些时间足够接近,可以忽略不计。您的程序可能需要从现在或以后使用其他模块,因此通常只需牺牲两微秒并在以后使用以避免此错误os
是有意义的。import os
我通常支持将 os 作为一个整体导入,但可以理解为什么有些人更愿意import os.path
在技术上更高效,并向代码的读者传达这是os
模块中唯一需要使用的部分。它本质上归结为我心中的一个风格问题。
常识在这里起作用:os
是一个模块,os.path
也是一个模块。因此,只需导入您要使用的模块:
如果你想使用os
模块中的功能,那么 import os
。
如果你想使用os.path
模块中的功能,那么 import os.path
。
如果要在两个模块中使用功能,则导入两个模块:
import os
import os.path
以供参考:
Lib/idlelib/rpc.py使用os
和导入os
.
Lib/idlelib/idle.py使用os.path
和导入os.path
.
Lib/ensurepip/ init .py使用两者并导入两者。
找不到任何明确的参考,但我看到os.walk的示例代码使用 os.path 但只导入 os