os.path
是一个模块。因此,导入它的首选方式是什么?# Should I always import it explicitly?
import os.path
或者...
# Is importing os enough?
import os
请不要回答"importing
os
works for me"。我知道,它现在可以工作(截至Python 2.6)。我想知道的是关于这个问题是否有任何官方建议。因此,如果您回答这个问题,请附上您的参考资料。os.path
是一个模块。因此,导入它的首选方式是什么?# Should I always import it explicitly?
import os.path
# Is importing os enough?
import os
os
works for me"。我知道,它现在可以工作(截至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
命令并访问子模块os.path
,那么当你不能执行import twisted
并自动访问twisted.spread
时,可能会感到惊讶。
os.name
是一个普通的字符串,而os.path
是一个模块,这很令人困惑。我总是用空的__init__.py
文件来构建我的包,这样在同一级别上我总是有一种类型的东西:一个模块/包或其他东西。许多大型Python项目采取这种方法,这 tends to make more structured code.
os.path
下的内容,则更显式并能让他人知道你真正关心的是什么,应使用import os.path
。os
模块下的内容,则应选择import os
。import os
在任何有意义的方式上都与“简单”有关。 简单≠短。 - Mike Grahamos.getcwd()
和os.path.isfile()
函数,那么同时导入import os
和import os.path
是愚蠢的。我的初衷是指出这一点。 - Nick T明确的答案: 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
模块的文档,而是针对 posixpath
的文档。 - wRARposixpath.py
(或 macpath.py
、ntpath.py
等)中。我相当确定他们的意思是不应该直接 import posixpath
(虽然可以),而应通过 os
导入模块以实现更好的可移植性。我认为他们并不打算推荐使用 import os
还是 import os.path
。 - flornquakeos.path
注入到 sys.modules
中的任何理由,除了允许使用 import os.path
导入。如果你不应该使用直接导入,为什么要在第一次添加 os.path
到 sys.modules
中呢? - chepner有趣的是,导入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
模块的这一部分。 对我来说,这实际上归结为一个风格问题。from os import path
将使对路径的调用更快。 - Justin Peelos
是一个模块,os.path
也是一个模块。因此,只需导入你想要使用的模块即可:
If you want to use functionalities in the os
module, then import os
.
If you want to use functionalities in the os.path
module, then import os.path
.
If you want to use functionalities in both modules, then import both modules:
import os
import os.path
参考资料:
Lib/idlelib/rpc.py使用os
并导入os
。
Lib/idlelib/idle.py使用os.path
并导入os.path
。
Lib/ensurepip/init.py同时使用并导入两者。
os.path
是一个特定于操作系统的模块的别名,该模块具有自己的名称。如果您已经导入了import os
,那么import os.path
就是多余的,因为os
也有一个属性path
,它指向相同的模块。(这并不是说它没有文档上的好处,只是不必要的。) - chepneros.path
的单独模块。它总是别名,要么是 posixpath
,要么是 ntpath
。 - chepner我没有找到任何权威参考资料,但是我看到os.walk的示例代码使用了os.path,但仅导入了os。
os.path
作为os
模块属性的一个示例,但也有一个使用from os.path import join, getsize
的示例。当然,这与from ... import ...
语句不允许像from os import path.join as join, path.getsize as getsize
这样的语句有很大关系。 - chepner
import os.path
并且认为那是更好的方式。当我说“这与os.path文档中所述的一致”时,我的意思是它在http://docs.python.org/library/os.path.html 中有它自己的页面。 - Mike Grahamos.py
确实注入到了sys.modules['os.path']
中。这就是为什么from os.path import something
实际上有效的原因。我很好奇这是什么时候引入的,然后查看了源代码。有趣的事实是:这来自1999年,最初包含在Python 1.5.2中。原始提交在此处。 - Bluehorn