6

我有相当多的 Python 脚本,其中包含其他 Python 脚本使用和引用的可重用代码。但是,这些脚本往往分散在不同的目录中,我发现必须在我的顶级脚本中包含(通常是多次)对 sys.path.append 的调用有点乏味。我只想在同一脚本中提供没有附加文件引用的“导入”语句。

目前,我有这个:

import sys
sys.path.append('..//shared1//reusable_foo')
import Foo
sys.path.append('..//shared2//reusable_bar')
import Bar

我的偏好如下:

import Foo
import Bar

我的背景主要是 .NET 平台,所以我习惯于使用元文件(如 *.csproj、*.vbproj、*.sln 等)来管理和包含源文件之外的实际文件路径引用。这允许我只提供“使用”指令(相当于 Python 的导入)而不暴露所有引用并允许在多个脚本中重用路径引用本身。

Python 是否对此有同等的支持,如果没有,有哪些技术和方法?

4

6 回答 6

4

简单的答案是将您的可重用代码放在您的站点包目录中,该目录位于您的 sys.path 中。

您还可以通过在路径中的某处添加 .pth 文件来扩展搜索路径。有关更多详细信息,请参阅https://docs.python.org/2/install/#modifying-python-s-search-path

哦,python 2.6/3.0 增加了对 PEP370、Per-user site-packages Directory 的支持

于 2008-11-13T19:02:41.780 回答
3

如果您的可重用文件被打包(也就是说,它们包含一个__init__.py文件)并且该包的路径是您的 PYTHONPATH 或 sys.path 的一部分,那么您应该能够做到

import Foo

这个问题提供了更多细节。

(注意:正如 Jim 所说,您也可以将可重用代码放到您的site-packages目录中。)

于 2008-11-13T19:02:27.523 回答
1

您可以将可重复使用的东西放入site-packages. 这是完全透明的,因为它是sys.path默认的。

您可以将someName.pth文件放入site-packages. 这些文件具有实际可重用内容所在的目录。这也是完全透明的。并且不涉及安装更改的额外步骤site-packages

您可以将可重用的东西的目录放在PYTHONPATH. 这有点不透明,因为您必须确保它已设置。不是火箭科学,但也不是完全透明的。

于 2008-11-13T20:15:37.267 回答
1

在一个项目中,我想确保用户可以将 python 脚本(基本上可以用作插件)放在任何地方。我的解决方案是将以下内容放入该项目的配置文件中:

[server]
PYPATH_APPEND: /home/jason:/usr/share/some_directory

这样,这将在程序启动时将 /home/jason 和 /usr/share/some_directory 添加到 python 路径。

然后,只需用冒号分割字符串并将这些目录添加到 sys.path 的末尾即可。您可能需要考虑将一个模块放在 site-packages 目录中,该目录包含一个读取该配置文件的函数并将这些目录添加到 sys.path (不幸的是,我目前没有时间编写示例) .

正如其他人所提到的,最好将尽可能多的内容放入站点包并使用 .pth 文件。但是,如果您有一个脚本需要导入一堆不在您不想从其他脚本导入的站点包中的东西,那么这可能是一个好主意。

(也可能有一种方法可以使用 .pth 文件来执行此操作,但我喜欢能够在放置其余配置信息的同一位置操作 python 路径)

于 2008-11-13T20:27:56.273 回答
1

最简单的方法是设置(或添加到)PYTHONPATH,并将您的模块和包放入(或符号链接)到 PYTHONPATH 中包含的路径中。

于 2008-11-14T00:43:32.980 回答
0

我的解决方案是打包一个可以导入模块的实用程序:my_util 在站点包中

import my_util

foo = myutil.import_script('..//shared1//reusable_foo')
if foo == None:
    sys.exit(1)


def import_script(script_path, log_status = True):
    """
    imports a module and returns the handle
    """
    lpath = os.path.split(script_path)

    if lpath[1] == '':
        log('Error in script "%s" in import_script' % (script_path))
        return None


    #check if path is already in sys.path so we don't repeat
    npath = None
    if lpath[0] == '':
        npath = '.'
    else:
        if lpath[0] not in sys.path:
            npath = lpath[0]

    if npath != None:
        try:
            sys.path.append(npath)
        except:
            if log_status == True:
                log('Error adding path "%s" in import_script' % npath)
            return None

    try:   
        mod =  __import__(lpath[1])
    except:
        error_trace,error_reason =  FormatExceptionInfo()
        if log_status == True:
            log('Error importing "%s" module in import_script: %s' % (script_path, error_trace + error_reason))
        sys.path.remove(npath)
        return None

    return mod
于 2008-11-14T01:08:06.723 回答