python - Python2:在子进程中暂停或使用yield,并从另一个进程中获取值
问题描述
我正在使用 python3 编写一个程序(假设main.py
下面在 python3 中运行)并利用现有的 python 扩展(用 c 编写,用 python2 编译),我没有源代码。可以说这个FrozenModule
类来自这个扩展。它确实做了很多事情,但只是试图在这里简化它。基本上我可以订阅它的事件,我真的只是控制回调函数。这意味着我可以通过更新回调函数来改变流程。
问题是我必须重新组织流程,并且每次调用回调函数时都想冻结/暂停。
我想要的最终结果是:
1:a,i,x
5:b,j,y
8:c,k,z
这是目前我在这里得到的,下面的代码。但它并没有真正按照我想要的方式工作。我添加了set_trace
只是为了检查流程。我得到正确输出的原因是因为我已经在和SELECTED
中定义了值。实际上我希望这个来自func2.py
func3.py
func1.py
简而言之,我真的很想func1.py
先运行,从中获取特定的键,然后运行func2.py
,它基本上会遍历它拥有的数据,直到它遇到那个事件/键,然后执行回调。暂停,对 做同样的事情func3.py
,然后也暂停。然后回到func1.py
并重新做一遍。
目前它的工作方式(不是下面的代码,而是我正在重写的当前程序),它func1.py
首先运行整个,然后键都是已知的,然后传递给func2.py
然后func3.py
我们分别获取值。最后,将其全部附加在一起以生成整个表,例如:
1:a,i,x
5:b,j,y
8:c,k,z
主要问题是这些工作非常大,可能需要很长时间。这也可能在中间崩溃,你的用户没有得到任何回报。所以新方法是逐行或逐行生成最终输出。而不是每列执行列,然后组合所有内容并将整个结果提供给用户。
下面代码的问题是,当我运行子进程时(我使用子进程的原因是因为扩展只需要在 python2 中),它真的会立即运行/迭代整个数据。我添加了对文件的写入只是为了确保发生这种情况。因此,只要您运行main.py
,甚至无需点击'c'
继续 set_trace,f2.txt
就已经拥有:
1,i
5,j
8,k
它最初应该是空的,然后当我'c'
进入 main 时,它应该只写 1 行,暂停,然后等待下一行。当然 set_trace 和写入文件只是为了测试。
简而言之,主要目标是逐行写入输出。两个主要问题是:1)每次调用回调时如何暂停子流程。2) 传递从func1.py
to获得的值func2.py
,func3.py
然后继续/取消暂停该过程。
对不起,很长的帖子。另外,我希望我的问题很清楚。
示例代码如下:
在 main.py
import subprocess
class ProcReader():
def __init__(self, python_file):
self.proc = subprocess.Popen(['python2', python_file], stdout=subprocess.PIPE)
def __iter__(self):
return self
def __next__(self):
while True:
line = self.proc.stdout.readline()
if not line:
raise StopIteration
return line
r1 = ProcReader("func1.py")
r2 = ProcReader("func2.py")
r3 = ProcReader("func3.py")
for l1, l2, l3 in zip(r1, r2, r3):
d1 = l1.decode('utf-8').strip().split(",")
d2 = l2.decode('utf-8').strip().split(",")
d3 = l3.decode('utf-8').strip().split(",")
print(f"{d1[0]}:{d1[1]},{d2[1]},{d3[1]}")
import pdb
pdb.set_trace()
在 func1.py
from frozenmodule import FrozenModule
def callback(k, v):
with open("f1.txt", 'a') as f:
print(f"{k},{v}")
f.write(f"{k},{v}\n")
fm.match = next(iter_items, None)
# somehow pause here, maybe use yield?
SELECTED = [1, 5, 8]
FAKE_DATA = {1: 'a',
5: 'b',
8: 'c'}
iter_items = iter(SELECTED)
fm = FrozenModule(FAKE_DATA, callback)
fm.match = next(iter_items, None)
fm.run()
在 func2.py
from frozenmodule import FrozenModule
def callback(k, v):
with open("f2.txt", 'a') as f:
print(f"{k},{v}")
f.write(f"{k},{v}\n")
# somehow pause here, maybe use yield?
# then get value from func1.py and set to fm.match
fm.match = next(iter_items, None)
SELECTED = [1, 5, 8]
FAKE_DATA = {1: 'i',
5: 'j',
8: 'k'}
iter_items = iter(SELECTED)
fm = FrozenModule(FAKE_DATA, callback)
fm.match = next(iter_items, None)
fm.run()
在 func3.py
from frozenmodule import FrozenModule
def callback(k, v):
with open("f3.txt", 'a') as f:
print(f"{k},{v}")
f.write(f"{k},{v}\n")
# somehow pause here, maybe use yield?
# then get value from func1.py and set to fm.match
fm.match = next(iter_items, None)
SELECTED = [1, 5, 8]
FAKE_DATA = {1: 'x',
5: 'y',
8: 'z'}
iter_items = iter(SELECTED)
fm = FrozenModule(FAKE_DATA, callback)
fm.match = next(iter_items, None)
fm.run()
在frozenmodule.py
class FrozenModule():
def __init__(self, fake_data, callback):
self.fake_data = fake_data
self.match = 0
self.callback = callback
def run(self):
for x in range(10):
if x == self.match:
self.callback(x, self.fake_data[x])
解决方案
推荐阅读
- excel - 如何在文本框中包含“单元格值”和文本
- javascript - 为什么灯箱不禁用滚动?
- javascript - 如何使用 jQuery/Javascript 更改 gridview 中的属性
- html - Intellisense 关闭了新文档
- html - 文本上的混合模式错误
- python - 从 Python 脚本中杀死由 Windows 上的批处理文件启动的外部进程
- javascript - 查找具有最匹配属性的项目
- ml.net - 选择 ml.net 功能以按单列对字符串进行分组
- image - 如何隐藏目录中的文件?
- multithreading - RAM 中的多线程布局是什么样的