python指定运行内存_在两次运行Python脚本之间将持久变量保存在内存中

在两次运行Python脚本之间将持久变量保存在内存中

有什么方法可以将结果变量保存在内存中,所以我不必每次运行脚本的开头都重新计算它?每次运行脚本时,我都会对数据集(从磁盘上读取)进行一系列(5-10秒)的确切操作。这不是什么大问题,因为我非常擅长使用交互式编辑器在两次运行之间调试代码。 但是有时候交互功能只是不切实际。

我知道我可以将结果写到磁盘上的文件中,但是如果可能的话,我想避免这样做。 这应该是一个解决方案,它在我第一次运行脚本时会生成一个变量,并将其保留在内存中,直到关闭外壳本身或明确告诉它退出为止。 像这样:

# Check if variable already created this session

in_mem = var_in_memory() # Returns pointer to var, or False if not in memory yet

if not in_mem:

# Read data set from disk

with open('mydata', 'r') as in_handle:

mytext = in_handle.read()

# Extract relevant results from data set

mydata = parse_data(mytext)

result = initial_operations(mydata)

in_mem = store_persistent(result)

我有点想说shelve模块可能就是我在这里想要的,但是看起来为了打开一个shelve变量,我必须为持久对象指定一个文件名,所以我不确定 这正是我要的东西。

关于搁置做我想做的任何提示? 还有其他想法吗?

7个解决方案

43 votes

您可以使用wrapper.py全局函数来重新执行主脚本的代码,从而实现类似目的。 您将需要编写一个包装器脚本,该脚本会导入您的主脚本,向其询问要缓存的变量,然后在包装器脚本的模块范围内缓存该副本,然后在需要时(当您在stdin上按Enter或其他命令时) ),它调用mainscript.py,但这一次将缓存的对象传递给它,以便您的脚本可以绕过昂贵的计算。 这是一个简单的例子。

wrapper.py

import sys

import mainscript

part1Cache = None

if __name__ == "__main__":

while True:

if not part1Cache:

part1Cache = mainscript.part1()

mainscript.part2(part1Cache)

print "Press enter to re-run the script, CTRL-C to exit"

sys.stdin.readline()

reload(mainscript)

mainscript.py

def part1():

print "part1 expensive computation running"

return "This was expensive to compute"

def part2(value):

print "part2 running with %s" % value

当wrapper.py运行时,您可以编辑mainscript.py,向part2函数添加新代码,并能够针对预先计算的part1Cache运行新代码。

Peter Lyons answered 2020-02-04T05:25:08Z

6 votes

为了将数据保留在内存中,该进程必须继续运行。 内存属于运行脚本的进程,而不属于Shell。 Shell无法为您保存内存。

因此,如果要更改代码并保持进程运行,则必须在更改模块后重新加载模块。 如果内存中的任何数据是更改的类的实例,则必须找到一种将其转换为新类的实例的方法。 有点混乱。 在这种热修补中,很少有语言能胜任(想到Lisp),并且出错的可能性很大。

Dietrich Epp answered 2020-02-04T05:25:34Z

6 votes

如果您只想保留一个对象(或对象图)供以后的会话使用,则搁置模块可能会显得过大。 只需腌制您关心的对象。 如果没有泡菜文件,则进行工作并保存泡菜;如果有泡菜文件,则将其加载。

import os

import cPickle as pickle

pickle_filepath = "/path/to/picklefile.pickle"

if not os.path.exists(pickle_filepath):

# Read data set from disk

with open('mydata', 'r') as in_handle:

mytext = in_handle.read()

# Extract relevant results from data set

mydata = parse_data(mytext)

result = initial_operations(mydata)

with open(pickle_filepath, 'w') as pickle_handle:

pickle.dump(result, pickle_handle)

else:

with open(pickle_filepath) as pickle_handle:

result = pickle.load(pickle_handle)

Matt Anderson answered 2020-02-04T05:25:54Z

3 votes

Python的货架是用于腌制(序列化)对象的持久性解决方案,并且是基于文件的。 优点是它直接存储Python对象,这意味着该API非常简单。

如果您真的想避免使用磁盘,那么您正在寻找的技术是“内存数据库”。 存在几种选择,请参见以下SO问题:Python中的内存数据库。

Ray Toal answered 2020-02-04T05:26:19Z

1 votes

这是一个依赖于操作系统的解决方案...

$mkfifo inpipe

#/usr/bin/python3

#firstprocess.py

complicated_calculation()

while True:

with open('inpipe') as f:

try:

print( exec (f.read()))

except Exception as e: print(e)

$./first_process.py &

$cat second_process.py > inpipe

这样,您就可以在第一个过程中更改和重新定义变量,而无需复制或重新计算任何内容。 与多处理,内存缓存,泡菜,搁置模块或数据库相比,它应该是最有效的解决方案。

如果您想在编辑器或IDE中迭代地编辑和重新定义second_process.py,直到您正确使用它,而不必等到第一个进程(例如,初始化一个大字典等)每次执行一次,它都非常好。 更改。

John answered 2020-02-04T05:26:48Z

0 votes

您可以执行此操作,但必须使用Python Shell。 换句话说,用于启动Python脚本的外壳程序必须是Python进程。 然后,所有全局变量或类将一直存在,直到您关闭外壳程序为止。

查看cmd模块,该模块使编写Shell程序变得容易。 您甚至可以进行安排,以使未在Shell中实现的所有命令都传递给系统Shell进行执行(无需关闭Shell)。 然后,您将必须实现某种命令,例如prun,该命令通过使用runpy模块运行Python脚本。

[http://docs.python.org/library/runpy.html]

您将需要使用init_globals参数将特殊数据传递到程序的名称空间,最好是dict或单个类实例。

Michael Dillon answered 2020-02-04T05:27:22Z

0 votes

您可以通过os在服务器上运行一个持久脚本,该os加载/计算,甚至定期将sql数据重新加载/重新计算到某种内存结构中,然后通过套接字从其他脚本获取内存中的数据。

Stephen answered 2020-02-04T05:27:43Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值