我应该使用`import os.path`还是`import os`?

时间:2010-04-27 19:26:27

标签: python coding-style python-import

根据official documentationos.path是一个模块。那么,导入它的首选方式是什么?

# Should I always import it explicitly?
import os.path

或者...

# Is importing os enough?
import os

请不要回答“导入os为我工作”。我知道,它现在也适用于我(从Python 2.6开始)。我想知道的是关于这个问题的任何官方建议。因此,如果您回答此问题,请发布您的推荐信息

7 个答案:

答案 0 :(得分:143)

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程序员早期对模块和包以及代码组织的困惑,我认为。这实际上有两个原因

  1. 如果您将os视为一个软件包,并且知道您可以import os并且可以访问子模块os.path,那么以后您可能会感到惊讶'执行import twisted并自动访问twisted.spread而不导入它。

  2. 令人困惑的是os.name是正常的东西,一个字符串,而os.path是一个模块。我总是使用空__init__.py文件构建我的包,以便在同一级别我总是有一种类型的东西:模块/包或其他东西。几个大型Python项目采用这种方法,这往往会产生更多结构化代码。

答案 1 :(得分:29)

根据Tim Peters的PEP-20,“明确比隐含更好”和“可读性计数”。如果os模块中的所有内容都位于os.path下,则import os.path会更明确,让其他人知道您真正关心的内容。

同样,PEP-20也说“简单比复杂更好”,所以如果你还需要更常规的os伞下的东西,import os将是首选。

答案 2 :(得分:15)

明确答案: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).
...

答案 3 :(得分:6)

有趣的是,导入os.path会导入所有操作系统。在交互式提示中尝试以下操作:

import os.path
dir(os)

结果与刚刚导入的os相同。这是因为os.path将根据您拥有的操作系​​统引用不同的模块,因此python将导入os以确定要为路径加载哪个模块。

reference

对于某些模块,说import foo不会公开foo.bar,所以我想这实际上取决于特定模块的设计。


通常,只需导入所需的显式模块应该稍微快一点。在我的机器上:

import os.path 7.54285810068e-06

import os 9.21904878972e-06

这些时间足够接近,可以忽略不计。您的程序可能需要现在或稍后使用os中的其他模块,因此通常只需牺牲两微秒并使用import os来避免以后出现此错误。我通常只是将os整体导入,但可以看出为什么有些人会更喜欢import os.path在技术上更高效,并向代码的读者传达这是os模块的唯一部分需要使用。它基本上归结为我脑海中的一个风格问题。

答案 4 :(得分:4)

找不到任何明确的引用,但我看到os.walk的示例代码使用os.path但只导入os

答案 5 :(得分:3)

常识在这里起作用:os是一个模块,os.path也是一个模块。因此,只需导入要使用的模块即可:

  • 如果要在os模块中使用功能,请导入os

  • 如果要在os.path模块中使用功能,请导入os.path

  • 如果要在两个模块中使用功能,请导入两个模块:

    import os
    import os.path
    

供参考:

答案 6 :(得分:-1)

我同意Mike的意见

我认为

import os没问题。

然后你必须提到这样的细节

os.path()

或者如果您正在调用模块中的模块

os.path.exists()
相关问题