根据官方文档,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起)。我想知道的是有关此问题的任何官方建议。因此,如果您回答这个问题,请发表您的参考资料。
Answers:
os.path
以一种有趣的方式工作。看起来os
应该是带有子模块的程序包path
,但实际上os
是一个普通的模块,sys.modules
可以注入魔力os.path
。这是发生了什么:
Python启动时,会将一堆模块加载到中sys.modules
。它们没有绑定到脚本中的任何名称,但是以某种方式导入它们时,您可以访问已创建的模块。
sys.modules
是在其中缓存模块的命令。导入模块时,如果已经将其导入到某处,则它将实例存储在中sys.modules
。os
是Python启动时加载的模块之一。它将其path
属性分配给特定于os的路径模块。
它会注入,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项目都采用这种方法,这往往会使代码更加结构化。
import os.path
自己做,认为那是更好的方法。“这与os.path的记录方式一致”是指在docs.python.org/library/os.path.html的文档中为它提供了自己的页面。
根据蒂姆·彼得斯(Tim Peters)撰写的PEP-20,“显式胜于隐式”和“可读性”。如果您需要从os
模块中获得的全部在之下os.path
,import os.path
则会更加明确,并让其他人知道您真正关心的是什么。
同样,PEP-20也说“简单胜于复杂”,因此,如果您还需要一些更笼统的资料os
,import os
则首选。
import os
以任何有意义的方式变得“简单” 到底是怎么回事。简单!=简短。
import os
和一个import os.path
是愚蠢的,如果你需要如os.getcwd()
和os.path.isfile()
最终答案: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
。
"Instead of importing this module directly, import os and refer to this module as os.path."
位于posixpath.py
(或macpath.py
, ntpath.py
等等)。我相当确定他们的意思是不应该import posixpath
(有效),而是通过导入模块os
以提高可移植性。我不认为他们打算给一个建议是否import os
或import os.path
优先。
有趣的是,导入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
如果速度是问题,将使对path的调用更快。
常识在这里起作用:os
是模块,os.path
也是模块。因此,只需导入要使用的模块:
如果要在os
模块中使用功能,请导入os
。
如果要在os.path
模块中使用功能,请导入os.path
。
如果要在两个模块中使用功能,则导入两个模块:
import os
import os.path
以供参考:
Lib / idlelib / rpc.py使用os
和导入os
。
lib / idlelib / idle.py使用os.path
和导入os.path
。