从不同的工作目录导入Python模块

时间:2009-06-25 23:03:09

标签: python

我有一个使用内置模块的Python脚本,但也导入了与主脚本本身位于同一目录中的许多自定义模块。

例如,我会打电话给

python agent.py

和agent.py有许多导入,包括:

import checks

其中检查位于与agent.py

相同的目录中的文件中
agent/agent.py
agent/checks.py

当前工作目录是代理/然后一切都很好。但是,如果我从任何其他目录调用agent.py,显然无法导入checks.py等错误。

我可以确保无论在何处调用agent.py,都可以导入自定义模块。

python /home/bob/scripts/agent/agent.py

7 个答案:

答案 0 :(得分:30)

实际上你的例子是有效的,因为checks.py与agent.py在同一个目录中,但是说checks.py在前面的目录中,例如;

agent/agent.py
checks.py

然后你可以做到以下几点:

path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
if not path in sys.path:
    sys.path.insert(1, path)
del path

请注意使用__file__

答案 1 :(得分:12)

你不应该使用sys.path。引用sys.path的Python 2.6文档:

  

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

=== amod.py ===
def whoami():
    return __file__

=== ascript.py ===
import sys
print "sys.argv", sys.argv
print "sys.path", sys.path
import amod
print "amod __file__", amod.whoami()

=== result of running ascript.py from afar ===
C:\somewhere_else>\python26\python \junk\timport\ascript.py
sys.argv ['\\junk\\timport\\ascript.py']
sys.path ['C:\\junk\\timport', 'C:\\WINDOWS\\system32\\python26.zip', SNIP]
amod __file__ C:\junk\timport\amod.py

如果它重新运行,最后一行当然会改为... amod.pyc。这看起来并不新颖,适用于Python 2.1和1.5.2。

为您调试提示:尝试两个简单的文件,就像我一样。尝试使用-v和-vv运行Python。向我们展示失败测试的结果,包括完整的回溯和错误消息,以及您的两个文件。告诉我们你正在运行什么平台,以及什么版本的Python。检查checks.py文件的权限。是否有导致干扰的checks.something_else?

答案 2 :(得分:7)

您需要将当前正在执行的模块的路径添加到sys.path变量中。由于您在命令行上调用它,因此脚本的路径将始终位于sys.argv [0]中。

import sys
import os
sys.path.append(os.path.split(sys.argv[0])[0])

现在,当导入搜索模块时,它还会查找托管agent.py文件的文件夹。

答案 3 :(得分:5)

有几种方法可以向PYTHONPATH添加内容。

阅读http://docs.python.org/library/site.html

  1. 在运行脚本之前设置PYTHONPATH环境变量。

    您可以执行此操作python -m agentagent.py运行PYTHONPATH

  2. .pth目录中创建lib/site-packages个文件。

  3. lib/site-packages

  4. 中安装模块

答案 4 :(得分:1)

我认为您应该考虑将代理目录放入正确的Python包中。然后将此包放在python路径的任何位置,您可以将检查导入为

from agent import checks

请参阅http://docs.python.org/tutorial/modules.html

答案 5 :(得分:1)

如果您知道check.py的完整路径,请使用此配方(http://code.activestate.com/recipes/159571/

如果要将目录添加到系统路径 - 此配方(http://code.activestate.com/recipes/52662/)。在这种情况下,我必须确定应用程序目录(sys.argv [0])将此值传递给AddSysPath函数。如果你想查看生产样本,请在这个帖子上发表评论,以便我稍后发布。

问候。

答案 6 :(得分:1)

为了概括我对您的目标的理解,您希望能够使用import custom_package_name导入自定义包,无论您从哪里调用python,无论您的python脚本位于何处。

许多答案都提到了我要描述的内容,但我觉得大多数答案都假设了很多以前的知识。我会尽量明确表达。

为了实现允许通过import语句导入自定义程序包的目标,必须通过python用于搜索程序包的路径在某处发现它们。 Python实际上使用多个路径,但我们只关注通过将sys.prefix(在您的python解释器中)的输出与/lib/pythonX.Y/site-packages(或lib/site-packages组合而找到的路径。如果您正在使用Windows,其中XY是您的python版本。

具体来说,通过运行:

找到python使用的路径
import sys
your_path = sys.prefix + '/lib/pythonX.Y/site-packages'
print(your_path)

如果您使用的是python 3.5,此路径应该类似于/usr/local/lib/python3.5/site-packages,但根据您的设置,它可能会有很大差异。

Python使用此路径(以及其他一些路径)来查找要导入的包。因此,您可以将自定义包放在/usr/local/lib/python3.5/site-packages文件夹中。别忘了在文件夹中添加 init .py文件。

再次具体,在终端类型:

cd your_path
cp path_to_custom_package/custom_package ./

现在您应该可以导入自定义程序包的所有内容,就像程序包位于同一目录中一样(例如import package.subpackage,程序包中的每个子程序包文件都应该有效。)