简体   繁体   English

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

[英]Should I use `import os.path` or `import os`?

According to the official documentation , os.path is a module.根据官方文档os.path是一个模块。 Thus, what is the preferred way of importing it?因此,导入它的首选方式是什么?

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

Or...或者...

# Is importing os enough?
import os

Please DON'T answer "importing os works for me".请不要回答“导入os对我有用”。 I know, it works for me too right now (as of Python 2.6).我知道,它现在也适用于我(从 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 .所以,如果你回答了这个问题,请张贴你的参考资料

os.path works in a funny way. os.path以一种有趣的方式工作。 It looks like os should be a package with a submodule path , but in reality os is a normal module that does magic with sys.modules to inject os.path .看起来os应该是一个带有子模块path的包,但实际上os是一个普通的模块,它使用sys.modules来注入os.path Here's what happens:这是发生的事情:

  • When Python starts up, it loads a bunch of modules into sys.modules .当 Python 启动时,它会将一堆模块加载到sys.modules They aren't bound to any names in your script, but you can access the already-created modules when you import them in some way.它们不绑定到脚本中的任何名称,但是当您以某种方式导入它们时,您可以访问已经创建的模块。

    • sys.modules is a dict in which modules are cached. sys.modules是缓存模块的字典。 When you import a module, if it already has been imported somewhere, it gets the instance stored in sys.modules .当你导入一个模块时,如果它已经被导入到某个地方,它会获取存储在sys.modules中的实例。
  • os is among the modules that are loaded when Python starts up. os是 Python 启动时加载的模块之一。 It assigns its path attribute to an os-specific path module.它将其path属性分配给特定于操作系统的路径模块。

  • It injects sys.modules['os.path'] = path so that you're able to do " import os.path " as though it was a submodule.它注入sys.modules['os.path'] = path以便您能够执行“ import os.path ”,就好像它是一个子模块一样。

I tend to think of os.path as a module I want to use rather than a thing in the os module , so even though it's not really a submodule of a package called os , I import it sort of like it is one and I always do import os.path .我倾向于将os.path视为我想使用的模块,而不是os模块中的东西,所以即使它不是一个名为os的包的子模块,我导入它有点像它是一个,我总是import os.path This is consistent with how os.path is documented.这与os.path的记录方式一致。


Incidentally, this sort of structure leads to a lot of Python programmers' early confusion about modules and packages and code organization, I think.顺便说一句,我认为这种结构导致许多 Python 程序员早期对模块和包以及代码组织感到困惑。 This is really for two reasons这真的有两个原因

  1. If you think of os as a package and know that you can do import os and have access to the submodule os.path , you may be surprised later when you can't do import twisted and automatically access twisted.spread without importing it.如果您将os视为一个包,并且知道您可以执行import os并可以访问子模块os.path ,那么当您无法执行import twisted并在不导入的情况下自动访问twisted.spread时,您可能会感到惊讶。

  2. It is confusing that os.name is a normal thing, a string, and os.path is a module.令人困惑的是os.name是一个普通的东西,一个字符串,而os.path是一个模块。 I always structure my packages with empty __init__.py files so that at the same level I always have one type of thing: a module/package or other stuff.我总是用空的__init__.py文件来构建我的包,这样在同一级别我总是有一种类型的东西:模块/包或其他东西。 Several big Python projects take this approach, which tends to make more structured code.几个大型 Python 项目采用这种方法,这往往会产生更结构化的代码。

As per PEP-20 by Tim Peters, "Explicit is better than implicit" and "Readability counts".根据 Tim Peters 的PEP-20 ,“显式优于隐式”和“可读性很重要”。 If all you need from the os module is under os.path , import os.path would be more explicit and let others know what you really care about.如果你从os模块中需要的一切都在os.path下,那么import os.path会更明确,让其他人知道你真正关心的是什么。

Likewise, PEP-20 also says "Simple is better than complex", so if you also need stuff that resides under the more-general os umbrella, import os would be preferred.同样,PEP-20 也说“简单胜于复杂”,因此如果您还需要位于更通用的os保护伞下的东西,那么import os将是首选。

Definitive answer: import os and use os.path .确定答案: import os并使用os.path do not import os.path directly.不要直接import os.path

From the documentation of the module itself:从模块本身的文档中:

>>> 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).
...

Interestingly enough, importing os.path will import all of os.有趣的是,导入 os.path 将导入所有的 os。 try the following in the interactive prompt:在交互式提示中尝试以下操作:

import os.path
dir(os)

The result will be the same as if you just imported os.结果将与您刚刚导入 os. This is because os.path will refer to a different module based on which operating system you have, so python will import os to determine which module to load for path.这是因为 os.path 将根据您拥有的操作系​​统引用不同的模块,因此 python 将导入 os 以确定要为路径加载哪个模块。

reference 参考

With some modules, saying import foo will not expose foo.bar , so I guess it really depends the design of the specific module.对于某些模块,说import foo不会暴露foo.bar ,所以我想这真的取决于特定模块的设计。


In general, just importing the explicit modules you need should be marginally faster.通常,仅导入所需的显式模块应该会稍微快一些。 On my machine:在我的机器上:

import os.path : 7.54285810068e-06 seconds import os.path : 7.54285810068e-06

import os : 9.21904878972e-06 seconds import os 9.21904878972e-06

These times are close enough to be fairly negligible.这些时间足够接近,可以忽略不计。 Your program may need to use other modules from os either now or at a later time, so usually it makes sense just to sacrifice the two microseconds and use import os to avoid this error at a later time.您的程序可能现在或以后需要使用os中的其他模块,因此通常牺牲两微秒并使用import os来避免以后出现此错误是有意义的。 I usually side with just importing os as a whole, but can see why some would prefer import os.path to technically be more efficient and convey to readers of the code that that is the only part of the os module that will need to be used.我通常支持将 os 作为一个整体导入,但可以理解为什么有些人更喜欢import os.path以在技术上更高效并向代码读者传达这是os模块中唯一需要使用的部分. It essentially boils down to a style question in my mind.它本质上归结为我心中的一个风格问题。

Common sense works here: os is a module, and os.path is a module, too.常识在这里起作用: os是一个模块,而os.path也是一个模块。 So just import the module you want to use:因此,只需导入您要使用的模块:

  • If you want to use functionalities in the os module, then import os .如果要使用os模块中的功能,请导入os

  • If you want to use functionalities in the os.path module, then import os.path .如果要使用os.path模块中的功能,请导入os.path

  • If you want to use functionalities in both modules, then import both modules:如果要在两个模块中使用功能,则导入两个模块:

     import os import os.path

For reference:以供参考:

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

I agree with Mike 我同意麦克

I think 我认为

import os is fine. import os很好。

You just then have to mention details like this 您刚才必须提到这样的细节

os.path()

or if you are calling a module within a module 或者如果您正在调用模块中的模块

os.path.exists()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM