如何在多个 python 环境和由主脚本控制的活动脚本之间共享数据?

How to share data between multiple python environments and active scripts controlled by a master script?

我找不到这方面的信息。我看过很多关于在同一环境中的脚本 运行 之间共享数据的 posts,但在不同环境之间则不然。

我正在使用 Anaconda,还有 16 个使用多个不同 python 版本的环境——python 3.5 到 3.8-用于 运行 各种 scripts/apps。我现在正在研究 shell 脚本和一个主 python 脚本,它将控制其他环境的启动、启动脚本、打开 OS 本机应用程序和自动化脚本任务,所有这些都将是在同一个 machine 上保存、移动和访问来自多个主文件夹的数据。我支持ose 主脚本将像一个迷你服务器一样运行,并且它也存在于自己的环境中。

我想弄清楚的是,是否有一种方法可以轻松地在环境之间传输数据,或者我是否必须将内容存储在 yaml 或 JSON 他们都可以访问的文件中(例如将自定义环境变量从主环境传递给所有其他环境,或者一个脚本让另一个知道它何时完成,或者检测特定终端何时 window 有 closed)?

我不需要 most 个脚本来直接在彼此之间共享数据。我需要将反馈从其他环境发送到主脚本,该脚本将控制一切并在其终端 window 中打印输出并启动 shell 脚本。我需要那个主脚本与其他 envs/scripts 通信来给他们新的任务并自己加载环境,所以它知道是时候做其他事情了——基本上是事件监听器甚至处理程序的东西(我假设) 以及监视文件夹。其中 Most 将连续 运行。某些脚本将同时 运行 来自同一环境中的它们自己的 shell,处理不同的数据,有时主脚本(或单个脚本)会暂停并等待用户反馈主脚本终端。

这听起来可能比实际情况更复杂,因为 most 事情是线性发生的,需要共享的数据是小事件和变量。一件事开始和结束,一个监视文件夹看到新文件,主人启动一个新的环境并启动一个脚本来处理它们,然后下一个开始,然后下一个,然后 4 个相同的东西开始,然后是一个应用程序打开 运行 任务和 closes,然后提示用户如何继续选择 ose 下一个任务 运行s,等等。

我发现这些包似乎对某些任务很有前途:

创建 lambda 函数似乎是使用 python 执行 os/system 命令的简单方法。现在我只需要找到让所有这些东西与主人交谈的方法,反之亦然,并共享一些数据。一个应用程序使用 jupyter lab,我不确定从另一个应用程序自动化它是否容易 env/script。

我不需要像 jupyter lab 这样带有 GUI 的东西,老实说我不喜欢它 UI,更喜欢使用单个主终端 window带有一些简单的用户输入选项。

如果方向正确,我们将不胜感激。

这里的解决方案似乎是使用 sockets,创建一个 server,然后在我需要使用的脚本中创建 clients。不确定为什么我的搜索没有显示套接字,但这是我需要的解决方案并且不需要依赖项。

套接字内置于 python 中,因此使用 import sockets 可以处理我需要的大部分内容。

最重要的是,import threading 因此客户端可以使用多个线程,我正在使用 import system 发送系统命令。线程被设置为守护进程,以避免在客户端未完全断开连接时出现任何问题。

这在本地网络上具有 运行 的优势,但也可用于更复杂的系统以连接到远程客户端和服务器。 运行 在本地,您的服务器可以使用其私有 IPv4 地址在一台机器上或在 Intranet 上发送和接收。

教程

我发现 this YouTube video Tech With Tim 完成了完整的基本设置,这对我来说是一个全新的帮助很大。

我最终为服务器和客户端设置了 类,因为没有它我需要的所有功能都无法正常工作。这个视频是让我弄湿的好方法,但远非我所需要的。

我还创建了一个独立的任务管理器脚本,它比试图让服务器做所有事情更好。

基本服务器设置

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDRESS)

之后,您需要一个函数来处理客户端消息和一个服务器本身的启动函数。使用 server.listen() 来侦听消息,并使用 while 循环来处理连接并为每个客户端启动新线程。

我有单独的主控制器脚本,因为我发现将服务器 运行 放在需要用户输入的同一个 window 中很麻烦。所以我只是以编程方式启动、调整和定位一个新的终端window,并在其中加载服务器脚本。

基本客户端设置

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDRESS)

与服务器一样,客户端也需要一个发送消息的功能。 Tim 有一个很好的方法,您首先从客户端发送一个小的 header 让它知道传入消息的字节数,然后再实际发送消息,以确保不会被截断。

变量

使用环境变量和 env 文件确实有助于简化此设置。我使用 python-dotenv 完成了此操作。确保在主脚本中将端口设置为 int,否则它可能会出错,因为它会将其视为字符串。

随着我使我的脚本更高级,我最终将我所有的变量和充满变量的字典放在我根据需要加载的自定义模块中。

HEADER = 64 # header bytes
PORT = int(os.getenv('PORT')) # make this an int
SERVER = os.getenv('SERVER') # server local IP
ADDRESS = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT = '!killClient'