如果存储运算形成的“中间量”

2021-10-14 20:24:17 +08:00
 gossip
断断续续接触 python 其实有一年了,没拿它干过重活儿,还是非常新手的状态。但是进来有个问题让我思考更多:
楼主本身背景经济学,我们经常用的软件包括 R,Stata 这种。笔者更熟练用 Stata

现在在用 python 做点题目,问题描述如下:
好比说我有两个 python 文件 A 和 B,由于两个功能的完全不同,而且为了以后逻辑清楚,特意分成了两个文件写

A 执行之后经过复杂的运算会产生一个列表 m, 我的 B 文件就从 m 开始继续加工 m

这样一来,我只需要运行 B 就行了,想知道如何让 A 中运算产生的 m 在运行 B 的时候自动就当做已知的(当前那环境中就有的)

就好像 A 和 B 连起来一起执行一样?

--------------------------------------------------
我遇到这个问题,就在想我貌似之前很少碰到这个问题,于是回想了下这种情景用 Stata 是如何处理的。
是这样的:
一般 A 文件先参与运算,算完之后打开 B 文件,只要 B 文件开头不写清空当前内容,那么 A 得到的结果自然在内存中,接着用就是了。
又或者:
A 文件先参与运算,算完了之后把整个结果(通常是数据集,类似于 python 中的 dataframe )保存成 Stata 的 dta 文件就行,运行 B 的时候,开头调入整个 dta 文件,就 OK 了。

这个问题麻烦在于,我 A 生成的是一个列表,如果我选择 with open.... write 一个文本文件当然可以,然后再从 B 中写一个 with open 读出来用一个列表接收,当然可以,但总觉得“不是那个味道”。

所以感觉 python 这种没有一个变量框全局地储存变量还是与数据软件挺大的不同呢,但今晚遇到问题了,才更有理解一些。

但我觉得,应该是更大的问题是我不太懂 python 的所谓“模块”的概念,既然一切 py 文件皆是模块,我是否可以在 B 中引入 A 中的结果呢,我知道可以引入 A 中的函数等,但是通过 A 运算得到的 m 有没有好的办法呢?

(我的 A 文件就类似于一个面向过程的流水账,一步步计算出结果的这种)
----------------------------------------------------
话比较啰嗦,谢谢大家了
4259 次点击
所在节点    Python
27 条回复
zk123
2021-10-14 20:44:08 +08:00
共享内存?一个双向队列解决?看了两遍,没太清楚要解决的关键点在哪里
acmore
2021-10-14 20:45:26 +08:00
其实 with open 用文件才是最正统的风格( Unix ),你的系统盘里就有一大堆这样的中间临时文件。
不过这个问题是不是可以用一个 main 函数来解决,main 调用 A 得到结果再传给 B,一切都在内存里发生。

Python 的模块引用的都是代码,而不是运行的结果。
GeruzoniAnsasu
2021-10-14 20:47:31 +08:00
> 感觉 python 这种没有一个变量框全局地储存变量还是与数据软件挺大的不同呢

有。

正经编程语言会有「作用域」的概念,参与运算的变量会分层暴露在各自的「作用域」里,越「内部」或者说越「局部」的变量,就越不可能被外界看到。

与之相反的,如果一个变量处于「全局作用域」中,那就可以在全局范围内引用,跟引用函数 /类 是一样的。

假设 A 文件有一个计算过程 calcNumA,最后得出来一个临时结果,你可以把临时结果直接放到文件最外面,比如

ACache = None
def calcNumA(args):
``...
``global ACache
``ACache = results

然后引入它:

import A

if A.ACache=None:
``A.calcNumA(...)

但良好的程序设计会遵循一定的设计规范和最佳实践,不会像这样直接暴露变量。此处展开就太多了,这个问题可以先不管,建议以后代码写多了慢慢填
GeruzoniAnsasu
2021-10-14 20:49:09 +08:00
至于列表,不是有{}和[]吗
rpman
2021-10-14 20:49:10 +08:00
假设你是写好文件然后跑 .py ,一般做法是用 pickle 把对象存成文件,然后下一个脚本载入对象
如果要模仿统计软件里的体验,最简单方法是用 jupyter notebook,想跑哪个 cell 就跑哪个 cell,变量在同一个 notebook 里共享
ch2
2021-10-14 20:49:41 +08:00
需要有“进程”这个概念
你的问题本质上是一个进程执行完之后如何让中间结果留给下一个进程接着用
还额外蕴含了一个信息:第一次执行完毕后你想让进程驻留,只保留数据,第二次运行还要使用新的代码,这是很难以方便直观的方法做到的
一次代码的运行会创建一个进程,它可以使用多个源代码模块。但是两次代码执行之间想要互通数据就得借助于外部手段,写文件是其中一种
如果你不想借助外部方法,就得把多次运行改进成一次运行,这样始终只会创建一个进程,就不需要走进程共享这一套流程了
rpman
2021-10-14 20:52:39 +08:00
至于真正生产代码,都会把功能都封装成函数,脚本只负责调用
nuistzhou
2021-10-14 20:53:43 +08:00
不需要啥临时文件。这…在 B 里直接调用 A 的函数就好了啊。具体来说,你在 A 里的计算逻辑写成一个 返回结果(对你来说这里是可能是 df )的函数,然后在 B 里调用 A 的这个函数并运行,结果自然就可以作为一个 B 里的变量直接用。
SenLief
2021-10-14 20:57:00 +08:00
模块?
jmc891205
2021-10-14 23:13:56 +08:00
把 A 里的逻辑封装成函数 在 B 里调用返回 m
Livid
2021-10-14 23:14:05 +08:00
kilasuelika
2021-10-15 01:59:10 +08:00
看你的表述,你需要应该是在同一个环境下执行 2 个文件:
exec(open("filea.py").read())
exec(open("fileb.py").read())

这样 fileb 中可以直接用 filea 中的变量
dangyuluo
2021-10-15 03:20:03 +08:00
如果 AB 是不同进程的话,一定不想存到文件里,可以考虑一种 IPC
ruxuan1306
2021-10-15 03:37:23 +08:00
看描述感觉你好像是在用 Matlab 、PyCharm 那种交互式的、可以保持上下文的执行工具。

模块化的做法是:
A 文件里内容写成一个大函数,B 文件里内容也写成一个大函数,然后建立一个`main.py`文件,导入 A 、B 文件内的两个函数,于是你就可以先执行 A 先获得中间结果:`data = A()`,再将中间结果喂给 B:`result = B(data)`。

未来直接运行`main.py`即可。
iceheart
2021-10-15 08:32:03 +08:00
用 mq 啊
zjsxwc
2021-10-15 08:40:01 +08:00
python 保存 session 状态还是很简单的,仅仅只需要对 globals()进行操作就行。

https://stackoverflow.com/questions/2960864/how-to-save-all-the-variables-in-the-current-python-session#answer-2961077
oott123
2021-10-15 08:47:50 +08:00
我倒觉得你需要的是一个 Jupyter Notebook
gaint97
2021-10-15 09:26:33 +08:00
我也是小白,感觉把 Adefine 个函数可行
ipwx
2021-10-15 10:56:26 +08:00
楼主能不能给代码,不然我们说的都是失真了的。
gossip
2021-10-15 11:11:52 +08:00
@ipwx 是的,主要里面有些数据库比较保密哈

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/807880

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX