Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python2:在子进程中暂停或使用yield,并从另一个进程中获取值_Python_Subprocess_Generator - Fatal编程技术网

Python2:在子进程中暂停或使用yield,并从另一个进程中获取值

Python2:在子进程中暂停或使用yield,并从另一个进程中获取值,python,subprocess,generator,Python,Subprocess,Generator,我正在使用python3编写一个程序(假设下面的main.py是在python3中运行的),并使用一个现有的python扩展(用c编写,用python2编译),我没有它的源代码。假设FrozenModule类来自此扩展。它确实做了很多事情,但只是试图在这里简化它。基本上我可以订阅它的事件,我真的可以控制回调函数。这意味着我可以通过更新回调函数来更改流 问题是我必须重新组织流,并且希望在每次调用回调函数时冻结/暂停 我想要的最终结果是: 1:a,i,x 5:b,j,y 8:c,k,z 这就是我现

我正在使用python3编写一个程序(假设下面的
main.py
是在python3中运行的),并使用一个现有的python扩展(用c编写,用python2编译),我没有它的源代码。假设
FrozenModule
类来自此扩展。它确实做了很多事情,但只是试图在这里简化它。基本上我可以订阅它的事件,我真的可以控制回调函数。这意味着我可以通过更新回调函数来更改流

问题是我必须重新组织流,并且希望在每次调用回调函数时冻结/暂停

我想要的最终结果是:

1:a,i,x
5:b,j,y
8:c,k,z
这就是我现在得到的,代码如下。但这并不是我想要的方式。我添加了
set\u trace
只是为了检查流程。我获得正确输出的原因是我已在
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'
继续设置跟踪,
f2.txt
将已经具有:

1,i
5,j
8,k
最初它应该是空的,然后当我在main中点击
'c'
时,它应该只写一行,暂停,然后等待下一行。当然,set_跟踪和写入文件只是为了测试

简而言之,主要目标是逐行写入输出。两个主要问题是:1)如何在每次调用回调时暂停子进程。2) 将从
func1.py
获得的值传递到
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])