关于python:我应该使用”import os.path”还是”import os”?

Should I use `import os.path` or `import os`?

(P)According to the official documentation,EDOCX1 commonline 0 is a module.Thus,what is the preferred way of importing it?(p)字母名称(P)Or…(p)字母名称(P)请不要回答"Importing EDOCX1 Please don't answer"Importing EDOCX1I know,it works for me too right now(as of Python 2.6).What I want to know is any official recommendation about this issue.So,if you answer this question,please post your references.(p)


os.path的工作方式很有趣。看起来os应该是一个带有子模块path的包,但实际上os是一个正常的模块,它可以用sys.modules神奇地注入os.path。以下是发生的事情:

  • 当python启动时,它将一组模块加载到sys.modules中。它们没有绑定到脚本中的任何名称,但是当您以某种方式导入它们时,可以访问已经创建的模块。

    • sys.modules是一种将模块缓存在其中的dict。当您导入模块时,如果它已经导入到某个地方,它将获取存储在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项目采用这种方法,这会使代码更加结构化。


  • 根据TimPeters的PEP-20,"显式优于隐式"和"可读性计数"。如果os模块的所有需求都在os.path下,import os.path将更加明确,并让其他人知道你真正关心的是什么。

    同样,PEP-20也会说"简单胜于复杂",所以如果你还需要更通用的os保护伞下的东西,import os会更受欢迎。


    明确答案:import os和使用os.path。不要直接使用cx1〔2〕。

    从模块本身的文档中:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> 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将导入所有操作系统。在交互式提示中尝试以下操作:

    1
    2
    import os.path
    dir(os)

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

    参考

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

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

    import os.path秒:7.54285810068e-06

    import os9.21904878972e-06

    这些时间非常接近,可以忽略不计。您的程序可能需要在现在或以后使用来自os的其他模块,因此通常只需要牺牲两微秒,并在以后使用import os来避免此错误是有意义的。我通常只支持将操作系统作为一个整体导入,但可以理解为什么有些人更喜欢import os.path在技术上更高效,并向读者传达代码,这是os模块中唯一需要使用的部分。它本质上归结为我心目中的一个风格问题。


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


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

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

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

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

      1
      2
      import os
      import os.path

    供参考:

    • lib/idlelib/rpc.py使用os并导入os

    • lib/idle lib/idle.py使用os.path并导入os.path

    • lib/ensurepip/init.py同时使用和导入两者。


    我同意迈克的看法

    我想

    import os很好。

    你刚才必须提到这样的细节

    1
    os.path()

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

    1
    os.path.exists()