Python: 当前目录是否自动包含在路径中?

31

Python 3.4:从阅读其他 SO 问题的经验来看,如果一个 moduleName.py 文件在你当前的目录之外,如果你想要导入它,必须使用 sys.path.insert(0, '/path/to/application/app/folder') 将其添加到路径中,否则 import moduelName 语句将导致以下错误:

ImportError: No module named moduleName

这是否意味着Python会自动将同一目录下的所有其他.py文件添加到路径中?在表面以下发生了什么,使您能够导入本地文件而无需附加Python的路径?那么__init__.py文件在表面下又是做什么的呢?


初始脚本的本地目录包含在路径中。 - Martijn Pieters
2个回答

28
Python会将初始脚本所在的目录作为sys.path的第一项添加:

在程序启动时初始化,此列表的第一项path[0]是包含用于调用Python解释器的脚本的目录。如果脚本目录不可用(例如,如果交互地调用解释器或从标准输入读取脚本),path[0]为空字符串,这将指示Python首先在当前目录中搜索模块。请注意,脚本目录是在由PYTHONPATH导致的条目之前插入的。

因此,在表面下发生的事情是Python已经为您将“本地”目录附加(或更确切地说是预先附加)到sys.path中。

这意味着,当搜索模块时,脚本所在的目录是首选的。

__init__.py与所有这些无关。 __init__.py是需要使目录成为(常规)包的;任何在Python模块搜索路径上找到的此类目录都被视为模块。


1
你有没有想过为什么只有在特定情况下才会添加当前目录,而不是一直添加?通常我在运行脚本时都希望包括当前目录,但这经常会让我和其他人出现问题。 - Alex Hall
4
@AlexHall 这里的“它”指的并不是当前工作目录,而是脚本所在的位置。你通常在当前工作目录中运行脚本,这使得它看起来像是当前工作目录,但这只是巧合,并且是个不幸的情况。你很少想要添加当前工作目录,因为这意味着脚本导入的内容取决于用户当前的文件系统位置,这会导致难以调试的问题。 - Martijn Pieters
1
当您运行不带限定路径的脚本 python filename.py 时,脚本没有完整路径,因此Python最终会将''添加到sys.path中,这意味着查找将使用当前工作目录。如果您的代码在运行其他导入之前使用了os.cwd(),那么您要避免这种情况。 - Martijn Pieters
@AlexHall,如果你真的非常想要将当前工作目录添加到路径中,那么就明确地添加它吧。sys.path.insert(0, '') - Martijn Pieters

1

当我从Intellij Idea运行Python脚本时,我遇到了同样的问题。

有一个脚本在其中

C:\Users\user\IdeaProjects\Meshtastic-python\meshtastic

它使用

from meshtastic import portnums_pb2, channel_pb2, config_pb2

并且失败了。 我意识到它正在寻找

C:\Users\user\IdeaProjects\Meshtastic-python\meshtastic\meshtastic

并在运行配置中更改了此脚本的工作目录

C:\Users\user\IdeaProjects\Meshtastic-python\meshtastic

C:\Users\user\IdeaProjects\Meshtastic-python

这样在执行期间可以找到工作目录下的这个模块。

C:\Users\user\IdeaProjects\Meshtastic-python\meshtastic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接