gpt4 book ai didi

Python 可以导入未安装的模块

转载 作者:太空狗 更新时间:2023-10-30 01:19:20 26 4
gpt4 key购买 nike

所以,我正在尝试打包我编写的 python 脚本,它有一个子模块,我们称它为 submodule。文件夹结构如下所示:

cool_script/
setup.py
cool_script.py
submodule/
__init__.py
implementation.py

现在,在多次调用 pip install .pip install -e . 之后,我遇到了可以全局导入 submodule 的情况。无论在我系统的哪个位置,这都将始终有效:

$ python3
[...]
>>> import submodule
>>> submodule.__file__
'/home/me/fake/path/cool_script/submodule/__init__.py'

但我不知道为什么。

我做的包又被卸载了,pip在其索引中找不到子模块。 dist-packages 中也没有任何内容,我手动删除了仍然在那里的 cool_script.egg-link:

$ ls /usr/local/lib/python3.4/dist-packages | ack cool 
$ ls /usr/local/lib/python3.4/dist-packages | ack submodule
$

PYTHONPATH 也是空的:

$ echo $PYTHONPATH

$

为什么 Python 知道 submodule 的位置?我怎样才能知道?

最佳答案

首先运行 python -c "import site; print(site.getsitepackages())"。它将打印如下列表:

['/XXX/something/site-packages']

通常此列表中只有一个路径,它指向 pip 安装脚本的目录。如果您好奇,可以ls 进入:ls/XXX/something/site-packages/

不过,更有趣的是,当您使用开发人员安装时,pip 会在该目录中放置一个“链接”文件(又名 pip install -e)。 “链接”文件以原始项目命名,末尾带有 .egg-link 扩展名。

所以您可能在该目录中有一个 cool_script.egg-link 文件。如果您尝试将其打印出来,您应该会发现其内容列出了模块的原始文件系统位置。像这样的东西:

$ cat /XXX/something/site-packages/cool_script.egg-link
/home/me/fake/path/cool_script/
.

这就是 pip 记录它在开发者模式下安装了一些东西的方式,但这并不是 Python 实际上知道如何找到你的模块的方式(那太容易了,对吧?:- )).

Python 不知道 .egg-link 文件,但它会读取 site-packages 目录中的所有 .pth 文件到获取 sys.path (*) 的附加路径。因此,为了使 Python 能够导入开发人员模式安装,pip 将所有路径写入单个 .pth 文件,通常称为 easy-install.pth(因为旧的 easy-install 工具实际上开创了该技术)。如果您打印该文件,您将获得在开发人员模式下安装的所有项目路径的列表:

$ cat /XXX/something/site-packages/easy-install.pth
/home/me/fake/path/cool_script/
/home/me/another/project/

并且您可以检查 easy-install.pth 中列出的所有路径确实已添加到您的 sys.path 中。

(*) 从技术上讲,读取那些 .pth 文件的 Python 部分是 site 模块,它通常在启动时自动导入。不过,有一个选项可以禁用 site 模块,例如使用 python -S。在这种情况下,您会看到 sys.path 既不包含 site-packages 目录也不包含开发人员安装路径。

关于Python 可以导入未安装的模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47576847/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com