如何在另一个Python脚本中使用subprocess运行时接收一个参数?

huangapple go评论62阅读模式
英文:

How to receive an argument in a python script while running it through subprocess in another python script?

问题

我不太擅长在这里提问问题,所以如果有任何细节遗漏,请告诉我。

我正在尝试从另一个脚本("s.py")中的循环多次运行一个Python脚本("o.py")。
"o.py"位于"s.py"所在目录内的子文件夹中。
我想要访问我在"s.py"中设置的一个变量(变量 "l"),在"o.py"中使用它。但由于我将"o.py"作为子进程运行(我不能以其他方式运行它,因为我没有开发这部分功能),所以我无法从"s.py"导入变量到"o.py",因为存在一些限制。
因此,作为一种解决方法,我想在"s.py"中以"l"作为输入变量运行脚本"o.py"。
我想知道如何在"s.py"和"o.py"文件中实现这一点。
我看过一些答案,但每个人都提到了子进程函数的代码,但没有提到如何在通过子进程执行的文件中接收变量(在这种情况下为"o.py")。

请注意,我需要并行化这个过程(多进程),并且每次,对于每个进程,"l"的值在子进程完成之前都不应该改变。

以下是"s.py"和"o.py"的示例代码:

s.py

import multiprocessing as mp
import subprocess

def processToParallelize():
    subprocess.call(["python_path", "o.py"], input=l, text=True)
    subprocess.call(["python_path", "o.py"], input=l, text=True)
    subprocess.call(["python_path", "o.py"], input=l, text=True)

if __name__ == '__main__':
        NUMBER_OF_TASKS = 2
        pool = mp.Pool(NUMBER_OF_TASKS)

        pool.map(processToParallelize, range(4))

        pool.close()
        pool.join()

o.py

r = # 这应该等于 "l"
x = someoperation(r)

其他与此主题相关的问题没有分享如何在子进程文件中接收输入参数的信息。这是我需要解决的重要部分。

英文:

I am not so good at asking questions here so please let me know if any detail is missing.

I am trying to run a Python script ("o.py") multiple times in a loop from another script ("s.py").
o.py is in a subfolder inside the directory where s.py is located.
I want to access a variable that I set in s.py (variable "l") in o.py. But since I am running o.py as a subprocess (I cannot run it any other way as I did not develop this part) I cannot import the variable from s.py to o.py because of some constraints.
So as a work around I would like to run the script o.py from s.py with "l" as the input variable.
I would like to know how can I accomplish this in both s.py and o.py files.
I read some answers but everyone has mentioned the code for the subprocess function, but nothing for receiving the variable in the file being executed through the subprocess (in this case o.py).

Please note that I need to parallelize this process (multiprocessing) and every time, for each process the value of "l" should not change until the subprocess is finished.

Here is a sample of how s.py and o.py look like:

s.py

import multiprocessing as mp
import subprocess

def processToParallelize():
    subprocess.call(["python_path" , "o.py"], input = l, text=true)
    subprocess.call(["python_path" , "o.py"], input = l, text=true)
    subprocess.call(["python_path" , "o.py"], input = l, text=true)

if __name__ == '__main__':
        NUMBER_OF_TASKS =2
        pool = mp.Pool(NUMBER_OF_TASKS)

        pool.map(processToParallelize, range(4))

        pool.close()
        pool.join()



o.py

r = # this should be equal to "l"
x = someoperation(r)

The other questions that were asked related to this topic did not share the information about how to receive the input argument in the subprocess files. That was an important part which I needed to be resolved.

答案1

得分: 0

看起来你正在尝试通过标准输入流(stdin)将信息传递给 o.py。如果是这样的话,那么 o.py 需要从stdin中获取数据。

假设 o.py 看起来像这样:

print('>>>>', input(), '<<<<')

即,它从stdin中读取并打印在“尖括号”之间的值。

现在我们的调用程序可能如下所示:

import subprocess
import multiprocessing

N = 5

PYTHON = '/Library/Frameworks/Python.framework/Versions/3.11/bin/python3.11'

def process(n: int):
    subprocess.run([PYTHON, 'o.py'], input=str(n), text=True)

def main():
    with multiprocessing.Pool(N) as pool:
        pool.map(process, range(N))

if __name__ == '__main__':
    main()

输出:

>>>> 0 <<<<
>>>> 2 <<<<
>>>> 1 <<<<
>>>> 4 <<<<
>>>> 3 <<<<

输出的顺序将是不确定的。

注意:使用 subprocess.run 而不是过时的 subprocess.call。

英文:

It looks as though you're trying to pass information to o.py via the standard input stream (stdin). If that's the case then o.py needs to be consuming data from stdin.

Let's assume that o.py looks like this:

print(&#39;&gt;&gt;&gt;&gt;&#39;, input(), &#39;&lt;&lt;&lt;&lt;&#39;)

i.e., it reads from stdin and prints the value between "chevrons".

Now our calling program could look something like this:

import subprocess
import multiprocessing

N = 5

PYTHON = &#39;/Library/Frameworks/Python.framework/Versions/3.11/bin/python3.11&#39;

def process(n: int):
    subprocess.run([PYTHON, &#39;o.py&#39;], input=str(n), text=True)

def main():
    with multiprocessing.Pool(N) as pool:
        pool.map(process, range(N))

if __name__ == &#39;__main__&#39;:
    main()

Output:

&gt;&gt;&gt;&gt; 0 &lt;&lt;&lt;&lt;
&gt;&gt;&gt;&gt; 2 &lt;&lt;&lt;&lt;
&gt;&gt;&gt;&gt; 1 &lt;&lt;&lt;&lt;
&gt;&gt;&gt;&gt; 4 &lt;&lt;&lt;&lt;
&gt;&gt;&gt;&gt; 3 &lt;&lt;&lt;&lt;

The order of output will be indeterminate.

Note: subprocess.run rather than the outdated subprocess.call

答案2

得分: 0

由于您的数据是一个简单的字符串,使用命令参数。

def processToParallelize():
    subprocess.call(["python_path", "o.py"], args=(l,))

o.py

import sys
l = sys.argv[1]
print(l)

还可以使用环境变量。

import sys

def processToParallelize():
    sys.environ["l"] = l
    subprocess.call(["python_path", "o.py"])

o.py

import sys
l = sys.environ["l"]
print(l)
英文:

Since your data is a simple string, use a command argument.

def processToParallelize():
    subprocess.call([&quot;python_path&quot; , &quot;o.py&quot;], args=(l,))

o.py

import sys
l = sys.argv[1]
print(l)

Its also common to use environment variables.

import sys

def processToParallelize():
    sys.environ[&quot;l&quot;] = l
    subprocess.call([&quot;python_path&quot; , &quot;o.py&quot;])

o.py

import sys
l = sys.environ[&quot;l&quot;]
print(l)

huangapple
  • 本文由 发表于 2023年7月12日 23:02:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76671991.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定