代码之家  ›  专栏  ›  技术社区  ›  davidmytton

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

  •  30
  • davidmytton  · 技术社区  · 17 年前

    我有一个python脚本,它使用内置模块,但也导入一些与主脚本本身在同一目录中存在的自定义模块。

    例如,我会打电话给

    python agent.py
    

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

    import checks
    

    其中checks与agent.py在同一目录下的文件中

    agent/agent.py
    agent/checks.py
    

    当当前工作目录为agent/时,一切正常。但是,如果我从任何其他目录调用agent.py,它显然无法导入checks.py等错误。

    我如何确保可以导入自定义模块,而不管从何处调用agent.py,例如

    python /home/bob/scripts/agent/agent.py
    
    7 回复  |  直到 8 年前
        1
  •  30
  •   Peter Ericson    17 年前

    实际上,您的示例是有效的,因为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__ .

        2
  •  12
  •   LondonRob    11 年前

    你不需要摆弄sys.path。 要引用python 2.6 docs for sys.path,请执行以下操作:

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

    === 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。这看起来并不新鲜,它与Python2.1和1.5.2一起工作。

    调试提示:尝试两个像我一样简单的文件。尝试使用-v和-v v运行python。向我们展示失败测试的结果,包括完整的回溯和错误消息,以及您的两个文件。告诉我们您在哪个平台上运行,以及Python的版本。检查checks.py文件的权限。有没有检查过?有什么东西引起了干扰?

        3
  •  7
  •   Christopher    17 年前

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

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

    现在,当import搜索该模块时,它还将查找托管agent.py文件的文件夹。

        4
  •  5
  •   S.Lott    17 年前

    有几种方法可以将内容添加到 PYTHONPATH .

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

    1. 设置 Python路径 运行脚本之前的环境变量。

      你可以做到这一点 python -m agent 运行 agent.py 从你 Python路径 .

    2. 创造 .pth 文件在你 lib/site-packages 目录。

    3. 将模块安装到 lib/站点包 .

        5
  •  1
  •   Lennart Regebro    17 年前

    我认为您应该考虑将代理目录制作成适当的python包。然后将这个包放在python路径的任何位置,您可以将检查作为

    from agent import checks
    

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

        6
  •  1
  •   Denis Barmenkov    17 年前

    如果你知道check.py的完整路径,使用这个配方( http://code.activestate.com/recipes/159571/ )

    如果您想将目录添加到系统路径——这个方法( http://code.activestate.com/recipes/52662/ )。在这种情况下,我必须确定应用程序目录(sys.argv[0])并将该值传递给addsyspath函数。如果你想看产品样本,请在这个线程上留下评论,我稍后会发布它。

    当做。

        7
  •  1
  •   saetch_g    8 年前

    为了概括我对您目标的理解,您希望能够使用 import custom_package_name 无论您从何处调用python,也不管您的python脚本位于何处。

    许多答案提到了我将要描述的内容,但我觉得大多数答案都假定有很多以前的知识。我会尽量直截了当。

    为了实现允许通过 import 语句,它们必须可以通过Python用于搜索包的路径在某个地方被发现。python实际上使用多个路径,但是我们只关注通过组合 sys.prefix (在python解释器中)使用 /lib/pythonX.Y/site-packages (或) lib/site-packages 如果您使用的是Windows),其中x.y是您的python版本。

    具体地说,通过运行以下命令找到您的Python使用的路径:

    import sys
    your_path = sys.prefix + '/lib/pythonX.Y/site-packages'
    print(your_path)
    

    这条路应该看起来像 /usr/local/lib/python3.5/site-packages 如果您使用的是python 3.5,但是根据您的设置,它可能会有很大的不同。

    python使用此路径(以及其他一些路径)查找要导入的包。所以你可以做的就是把你的定制包放在 /usr/local/lib/python3.5/站点包 文件夹。不要忘记添加 初始化 .py文件到文件夹。

    再次采用混凝土,终端类型:

    cd your_path
    cp path_to_custom_package/custom_package ./
    

    现在,如果自定义包位于同一目录(即 import package.subpackage 对于包中的每个子包文件都应该有效)。