使用 ._pth 时脚本目录不包含在 sys.path 中

Script directory not included in sys.path when a ._pth is in use

我正在尝试解决与在我编写的 Python 脚本中导入模块相关的奇怪问题。实现该模块的文件与主 Python 脚本位于同一目录中。

当我使用 ActivePython 时,Python 脚本完美运行。但是,当我使用 Embedded Distribution 时出现以下错误。

ModuleNotFoundError: No module named 'pyWhich'

我已将行为差异追溯到 sys.path 真正在嵌入式分发中设置的方式。

在 ActivePython 中,我的脚本运行的环境,sys.path 中的第一个条目是包含脚本的目录。在嵌入式分发版中,没有包含脚本的目录条目。

嵌入式分发使用 _pth 文件来设置 sys.path。我正在使用默认的 ._pth 文件,为方便起见,我将其包含在下面。

python36.zip
.

# Uncomment to run site.main() automatically
#import site

我的问题是,我需要在我的 _pth 文件中添加什么神奇的咒语来告诉 Python 将包含我 运行 在 sys.path 中,这样我的脚本就可以与嵌入式分发一起使用。 path configuration files 上的文档似乎不包含此信息。

你试过了吗sys.path.append('C:/documents/folder/blah...') (正确的文件夹位置)

我仍然希望有一个神奇的咒语可以添加到我的 _pth 文件中,上面写着 "please put the directory containing any script I run in sys.path" 这样我就不必修改我的所有脚本。不过,也有可能根本就没有这样的魔法咒语。

我发现将以下魔法咒语添加到 Python 脚本后,可以达到预期的效果。而且,与您可能在野外找到的其他解决方案不同,这个解决方案将在 cx_Freeze 和 IDLE 的上下文以及基于简单 file 的任何其他上下文中工作解决方案将不起作用。

import inspect
import os
import sys

# Add script directory to sys.path.
# This is complicated due to the fact that __file__ is not always defined.

def GetScriptFile():
    """Obtains the full path and file name of the Python script."""
    if hasattr(GetScriptFile, "file"):
        return GetScriptFile.file
    ret = ""
    try:
        # The easy way. Just use __file__.
        # Unfortunately, __file__ is not available when cx_freeze is used or in IDLE.
        ret = os.path.realpath(__file__)
    except NameError:
        # The hard way.
        if len(sys.argv) > 0 and len(sys.argv[0]) > 0 and os.path.isabs(sys.argv[0]):
            ret = os.path.realpath(sys.argv[0])
        else:
            ret = os.path.realpath(inspect.getfile(GetScriptFile))
            if not os.path.exists(ret):
                # If cx_freeze is used the value of the ret variable at this point is in
                # the following format: {PathToExeFile}\{NameOfPythonSourceFile}. This
                # makes it necessary to strip off the file name to get the correct path.
                ret = os.path.dirname(ret)
    GetScriptFile.file = ret
    return GetScriptFile.file

def GetScriptDirectory():
    """Obtains the path to the directory containing the script."""
    if hasattr(GetScriptDirectory, "dir"):
        return GetScriptDirectory.dir
    module_path = GetScriptFile()
    GetScriptDirectory.dir = os.path.dirname(module_path)
    return GetScriptDirectory.dir

sys.path.insert(0, GetScriptDirectory())

顺便说一句,如果你想看到它的实际效果,我已经在我的 Python Which project 中实现了它。

我的解决方案是删除此文件:

python39._pth

这允许 Pip 工作,也允许来自同一目录的 import。 或者你可以得到这个:

https://nuget.org/packages/python

点击“下载包”,即可像Zip文件一样解压