如何在Python中控制导入路径?

如何在Python中控制导入路径?,python,Python,我是Python新手。我在一家公司工作,他们用Python构建了一个大型系统。当系统运行时,他们使用专有系统来管理路径,但现在我被要求构建一个独立的脚本,与他们系统中的一些代码交互。遗憾的是,我的独立脚本不会在他们使用的路径管理器下运行,所以我需要自己找出路径 例如,我有一行: from hark.tasks import REPLY_LINE 这实际上是从他们的一些旧代码中复制的。在这种情况下,脚本可以找到hark,但是hark有一个\uuuu init\uuuuuu.py文件,这就是问题的

我是Python新手。我在一家公司工作,他们用Python构建了一个大型系统。当系统运行时,他们使用专有系统来管理路径,但现在我被要求构建一个独立的脚本,与他们系统中的一些代码交互。遗憾的是,我的独立脚本不会在他们使用的路径管理器下运行,所以我需要自己找出路径

例如,我有一行:

from hark.tasks import REPLY_LINE
这实际上是从他们的一些旧代码中复制的。在这种情况下,脚本可以找到hark,但是hark有一个
\uuuu init\uuuuuu.py
文件,这就是问题的开始。所以我得到这个:

meg/src/python2/hark/hark/__init__.py in <module>()
      5 from flask import jsonify, render_template, request
      6 import jinja2
----> 7 import logbook, logbook.compat
      8 
      9 from healthhark.context import Ghost, g
我明白了:

meg/zurge/opt/python2.7/lib/python2.7/site-packages/logbook
meg/zurge/opt/python2.7-hark/lib/python2.7/site-packages/logbook
meg/zurge/opt/python3.4/lib/python3.4/site-packages/logbook
正如我所说,他们有一个专有的路径管理器,通常告诉每段代码在哪里可以找到它应该包含的包,但我正在构建一个独立的应用程序

我对Python了解不多,但我想知道他们是否是一种惯用的Python方式来包含位于如此遥远的目录中的包


而且,在任何人建议安装
pip
之前,我们根本不依赖全局安装

最好的解决方案可能是或。这将允许您定义一个包含脚本所需的所有库的环境。这不会是全球性的

这可以通过以下方式完成:

  • 创建一个定义所需库的
  • 安装pip和VirtualNVRapper
  • source/usr/local/bin/virtualenvwrapper.sh
  • workon hark_task_script_env|||(mkvirtualenv hark_task_script_env&pip install-r requirements.txt)
  • python您的脚本.py
VirtualEnvrapper将环境安装到主目录中的文件夹中。普通virtualenv库将环境安装到项目中的文件夹中。除此之外,它们是等价的

我真的建议使用它们,而不是使用专有的包管理器。如果您必须使用proprietry包管理器,那么访问包加载器是合理的

如果这真的不令人满意,那么您可以如下攻击包加载器(假设您使用*nix系统)。这是一个用zsh编写的shell脚本。如果您的系统没有可用的shell,希望您可以在受支持的shell中重写它:

#!/bin/zsh

setopt extended_glob

function find_package_init_files () {
    locate __init__.py
}

# Get the containing folder of a file or a folder
function file_or_folder_to_parent_folder () {
    while read file_or_folder
    do
        echo ${file_or_folder:h}
    done
}

# Exclude folders where the parent folder also has an __init__.py file in it
function exclude_inner_packages () {
    while read init_file_folder
    do
        init_file_parent_folder=${init_file_folder:h}
        if [ ! -e ${init_file_parent_folder}/__init__.py ]
        then
            echo ${init_file_folder}
        fi
    done
}

# This produces an array of all folders
# that contain at least one python package
function get_distinct_python_package_folders () {
    find_package_init_files |
        file_or_folder_to_parent_folder |
        exclude_inner_packages |
        file_or_folder_to_parent_folder |
        sort |
        uniq
}

PYTHONPATH=${(j/:/)$(get_distinct_python_package_folders)} YOUR_SCRIPT_HERE
您可能需要更新此脚本以将默认python路径放在首位,并且请记住,这是一种非常笨拙的方法。如果一个系统上安装了多个版本的库,那么最终可能使用的版本将定义不清


使用适当的包管理器(即使是适当的包管理器)是最好的方法。

python始终包含站点包。。。在python
print sys.path
中,您始终可以直接在python中修改sys.path,或指定$PYTHONPATH环境变量,该变量是路径搜索位置的列表。。。还有,你说我们根本不依赖全局安装是什么意思?我无法想象,除了你编写的模块之外,你的站点包文件夹中没有其他安装
#!/bin/zsh

setopt extended_glob

function find_package_init_files () {
    locate __init__.py
}

# Get the containing folder of a file or a folder
function file_or_folder_to_parent_folder () {
    while read file_or_folder
    do
        echo ${file_or_folder:h}
    done
}

# Exclude folders where the parent folder also has an __init__.py file in it
function exclude_inner_packages () {
    while read init_file_folder
    do
        init_file_parent_folder=${init_file_folder:h}
        if [ ! -e ${init_file_parent_folder}/__init__.py ]
        then
            echo ${init_file_folder}
        fi
    done
}

# This produces an array of all folders
# that contain at least one python package
function get_distinct_python_package_folders () {
    find_package_init_files |
        file_or_folder_to_parent_folder |
        exclude_inner_packages |
        file_or_folder_to_parent_folder |
        sort |
        uniq
}

PYTHONPATH=${(j/:/)$(get_distinct_python_package_folders)} YOUR_SCRIPT_HERE