2009-06-25 68 views
28

我有一个使用内置模块的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 
+0

而结果是什么?你打算接受答案吗? – 2009-07-03 09:47:09

+0

一旦我尝试了代码,我会接受一个答案,我几个星期不会这样做。我没有看到任何特别的匆忙。 – DavidM 2009-07-03 10:40:38

+0

试过了什么代码?正如我试图用一个例子来指出的那样,正如其他一两个人所说的那样,你所说的你应该做的只是工作而已,并且记录下来只是工作。不要“尝试代码”,请告诉我们(正如我所建议的那样)应该包含在您的问题中的基本信息(平台,Python版本,完整追溯和错误信息)以及我建议的初级调试。几分钟的时间;六人“冲”给你一个答案。 – 2009-07-06 02:01:57

回答

26

实际上你的例子工作原理是因为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__

+0

有什么要注意关于删除路径?为什么这个特殊? – 2014-05-13 04:17:34

6

您需要将当前正在执行的模块的路径添加到sys.path变量中。既然你在命令行中调用它,那么脚本的路径将始终在sys.argv [0]中。

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

现在,当导入搜索模块时,它也会查看承载agent.py文件的文件夹。

5

有几种方法可以将其添加到PYTHONPATH

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

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

    您可以这样做python -m agent从您的PYTHONPATH运行agent.py

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

  3. 安装您的模块在lib/site-packages

11

你不应该需要摆弄sys.path。引用sys 2.6的Python 2.6文档。路径:

如在程序启动时,该列表的第一项, 路径[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?

1

我认为你应该考虑把agent目录变成一个合适的Python包。然后你在任何地方把这个包Python路径上,你可以导入支票

from agent import checks 

http://docs.python.org/tutorial/modules.html

0

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

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

为了实现允许通过import语句导入自定义包的目标,它们必须在python用来搜索包的路径的某处可以发现它们。 Python实际上使用多条路径,但我们只关注可以通过将sys.prefix(在Python解释器中)的输出与/lib/pythonX.Y/site-packages(或如果您使用的是Windows,则为lib/site-packages)的输出组合在一起找到的那个路径,其中X.Y是您的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每个子包文件在你的软件包应该工作)。