我正在 Linux 上使用 python 绑定(bind)创建一个 Gtk4 应用程序。我也在使用 Flatpak。 所以我正在创建一个扩展/插件系统,用户可以定义他的主模块来调用特定文件,然后加载它。一切正常,但当用户使用 NumPy 或 pandas 等外部库的导入时,它将开始在 flatpak 沙箱内查找,这是正常的。我想知道如何告诉 python 解释器使用系统的模块来导入插件,而不是查看应用程序的模块。
用户的代码和要求应独立于应用程序的要求。
这就是我加载模块的方式:
extension_module = SourceFileLoader(file_name, module_path).load_module()
extension_class = getattr(dataset_module, class_name)
obj = extension_class()
这是加载类的示例
该模块的绝对路径为/home/user/.extensions/ext1/module.py
import numpy as np
class Module1:
def __init__(self):
self.data = np.array([1, 2, 3, 4, 5, 6])
def get_data(self):
return self.data
我尝试使用
os.path.append('/usr/lib64/python-10.8/site-packages')
已添加,但在沙盒环境中。
我考虑过手动查找用户导入,就像用户 import pandas 会尝试在系统中查找已安装的 python 包并使用 importlib 或 SourceFileLoader 来加载它一样,但我认为这不是一个好方法做吧。
最佳答案
所以,最后,经过一天的阅读 Flatpak docs ,我找到了办法。
我必须添加参数--filesystem=home
。该参数将使您能够访问用户的目录。当您使用pip安装软件包时,软件包将安装在以下目录~/.local/lib/python3.10/site-packages/
中。要让 python 解释器搜索该文件夹中的包,您可以将其添加到这样的路径中。
import sys
sys.path.append('~/.local/lib/python3.10/site-packages/')
注1:就我而言,这已经足够了,因为该应用程序是用于学习而不是严肃的,所以它是0安全问题。
我使用的是 openSUSE Tumbleweed,所以我有 python 3.10.11,Flatpak 运行时有 python 3.10.6。因此,一些拥有旧发行版或像 Ubuntu 或 Debian 这样的发行版的用户可能没有最新的 python 版本,并且可能会遇到兼容性问题。
更好的解决方案是在用户本地目录 f.g ~/.cache/myapp/packages
中创建一个简单的文件夹,然后可以将其添加到 flatpak list 文件 --filesystem =~/.cache/myapp:create
这样您就可以映射要从沙箱访问的文件夹,并且选项 :create 将创建该文件夹(如果该文件夹不存在)。然后我用你的 python 脚本根据外部脚本中使用的导入来安装所需的包。在 python 中,将文件夹路径添加到路径 sys.path.append('~/.cache/app/packages/')
。
注意2:当您想要创建插件系统时,直接将脚本导入到代码中是不安全的,最好创建一个执行这些脚本的子进程,这样您就可以将代码与外部隔离代码。您可以使用IPC协议(protocol)或其他技术来更改主进程和子进程之间的数据。
关于python - 我如何告诉在 flatpak 沙箱内运行的 python 解释器使用主系统中的库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75043540/