在脚本调用之间保持Python变量
我有一个python脚本,需要将大文件从磁盘加载到变量。这需要一段时间。该脚本将从另一个应用程序多次调用(仍然未知),使用不同的选项并使用stdout。是否有可能避免为脚本的每次调用读取大文件?在脚本调用之间保持Python变量
我想我可以有一个大的脚本在后台运行,保存变量。但是,那么我怎样才能用不同的选项调用脚本并从另一个应用程序读取stdout?
(我误会了原来的问题,但我写的第一个答案有不同的解决方案,这可能是有人恰当的情况下是有用的,所以我保持一个不变并提出第二个解决方案。 )
对于单台机器,操作系统提供的管道是您寻找的最佳解决方案。
本质上,您将在python中创建一个永久运行的进程,该进程从管道读取,并处理进入管道的命令,然后打印到sysout。
参考:http://kblin.blogspot.com/2012/05/playing-with-posix-pipes-in-python.html
从上述源
工作量 为了模拟我的工作量,我想出了下面的简单脚本调用pipetest.py接受一个输出文件名,然后写一些文本到该文件中。
#!/usr/bin/env python
import sys
def main():
pipename = sys.argv[1]
with open(pipename, 'w') as p:
p.write("Ceci n'est pas une pipe!\n")
if __name__ == "__main__":
main()
守则 在我的测试,此“文件”将是我的包装的代码创建了一个FIFO。包装代码的实现如下,我会去对代码进行详细进一步下跌这篇文章:
#!/usr/bin/env python
import tempfile
import os
from os import path
import shutil
import subprocess
class TemporaryPipe(object):
def __init__(self, pipename="pipe"):
self.pipename = pipename
self.tempdir = None
def __enter__(self):
self.tempdir = tempfile.mkdtemp()
pipe_path = path.join(self.tempdir, self.pipename)
os.mkfifo(pipe_path)
return pipe_path
def __exit__(self, type, value, traceback):
if self.tempdir is not None:
shutil.rmtree(self.tempdir)
def call_helper():
with TemporaryPipe() as p:
script = "./pipetest.py"
subprocess.Popen(script + " " + p, shell=True)
with open(p, 'r') as r:
text = r.read()
return text.strip()
def main():
call_helper()
if __name__ == "__main__":
main()
使它成为一个(web)microservice:将所有不同的CLI参数形式化为HTTP端点并从主应用程序向其发送请求。
您可以将处理后的值存储在文件中,然后从另一个脚本中读取该文件中的值。
>>> import pickle as p
>>> mystr="foobar"
>>> p.dump(mystr,open('/tmp/t.txt','wb'))
>>> mystr2=p.load(open('/tmp/t.txt','rb'))
>>> mystr2
'foobar'
我想我没有那么清楚。没有太多的处理正在进行。但是从硬盘读取并将其放入RAM需要一段时间。 – NoMorePen
既然你已经可以将数据读入一个变量,那么你可以考虑使用内存映射文件mmap。这是安全的,如果多个进程只读它 - 支持一个作家需要一个锁定协议。
假设你不熟悉内存映射对象,我会打赌你每天都在使用它们 - 这就是操作系统如何加载和维护可执行文件。基本上你的文件成为分页系统的一部分 - 尽管它不一定要采用任何特殊的格式。
当您将文件读入内存时,它不太可能全部加载到内存中,当“真实”内存过度订阅时会将其分页。通常这种分页是相当大的开销。内存映射文件就是您的数据“准备就绪”。读入内存没有开销(虚拟内存,即),它只要你映射它就在那里。
当您尝试访问数据时,页面错误发生并且一个子集(页面)被加载到RAM中 - 全部由操作系统完成,程序员不知道这一点。
当文件保持映射状态时,它连接到寻呼系统。映射相同文件的另一个进程将访问同一对象,但前提是尚未做出更改(请参阅MAP_SHARED
)。
它需要一个守护进程来将内存映射对象保持在内核中,但除了创建链接到物理文件的对象之外,它不需要做其他任何事情 - 它可以休眠或等待关闭信号。
其他进程打开该文件(使用os.open()
)并映射该对象。
见实例文档中,here也Giving access to shared memory after child processes have already started
你可以根据答案[这里](http://stackoverflow.com/questions/6687660/keep-persistent-variables-in尝试的方法 - 内存 - 之间的挤兑 - 的 - Python的脚本)。如果你使用的是Python 3,'reload'必须从importlib import reload'导入' –