Python:运行脚本A处理脚本B

时间:2016-05-31 23:04:58

标签: python shell command-line argparse

我有一个script_A,它使用我用来执行函数的argparser来处理不同的输入。我现在需要脚本B来调用并让所有脚本A从内部运行(让它处理不同的输入)。我正在使用Windows。

目标: Script_B将根据script_A的输出进行进一步分析。 Script_A的行为根据传递的参数选项而变化。 Script_B的行为总是一样的。我宁愿不将script_A和script_B合并成一个庞大的脚本。

目标已更新:为了使script_B运行良好,我需要运行script_A,然后传递一个字典D,即计算的字典D(从A输出)传递给B.只有在所有script_A运行之前,才会计算字典。

这就是Script_A的样子

import sys
import os
from argparse import ArgumentParser

def function 1:
    #it does stuff....

def function 2:
    #it does other stuf...

if __name__ == "__main__":
    parser = ArgumentParser(description = "functionA.py -i [--print]
    parser.add_argument('-i', '--id', help="Please write A or B", required=True)
    parser.add_argument('-r', '--re', help="Please write C or D, required=True)

    sysargs = parser.parse_args()

    #Variable definitions

    if str(sysargs.id) == "A":
        #Uses file A located in directory X to perform analysis
        #calls function A to perform analysis
    elif str(sysargs.id) == "B":
        #Uses file B located in Directory Y to perform analysis
        #calls function B to perform analysis

    if str(sysargs.re) == "C"
        #Provides thorough printout of analysis (more in depth for debugging)
    if str(sysargs.re) == "D"
        #Does Nothing (no debugging option)

脚本A运行正常,它在我使用时完成它的工作。我使用命令行参数来提交输入,必需的,有时是可选的。

这就是脚本B,我尝试了以下内容:

1

import sys
import numpy as np
import os
import script_A

os.system("script_A.py", -i "A" -r "C")

#Other stuff that script B does

2

import sys
import os
import script_A

exec(script_A.py[-i "A" -r "C"])

#Other stuff that script B does

第3

import os
import sys
from subprocess import call

subprocess.call("script_A.py", -i "A" -r "C")

#Other stuff that script B does

我看过这里:Calling an external command in Python

在这里:importing a python script from another script and running it with arguments

但未能从他们所说的内容中找到答案。任何帮助是极大的赞赏。我还是Python的初学者。

我根据评论尝试了以下内容:

1

import subprocess
import script_A

p.subprocess.Popen("script_A.py", "-i", "A", "-r", "none", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)


(stdoutput, erroutput) = p.communicate()

TypeError:__ init_()为关键字参数'stdout'

获取了多个值

我尝试添加self参数但是我收到以下错误

p.subprocess.Popen("script_A.py", "-i", "A", "-r", "C", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

TypeError:__ init_()为关键字参数'stderr'

获取了多个值

2

import subprocess
import script_A

process= Popen(["script_A", "-i", "A", "-r", "C"], stdout = subprocess.PIPE, stderr=subprocess.STDOUT)

output = process.communicate()

OSError:[ERRno2]没有这样的文件或目录

执行子项目中/subprocess.py目录中的

错误

提出child_exception

我不知道这意味着什么。

3 个答案:

答案 0 :(得分:1)

p = subprocess.Popen("your_a_code_with_args_here",
                     shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

(stdoutput, erroutput) = p.communicate()

然后你的B代码可以根据A代码的输出做事。

答案 1 :(得分:1)

我已将您的A浓缩为:

import argparse

def function_1():
    print('function 1')

def function_2():
    print('function 2')

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('-i', '--id', choices=['A','B'], default='A')
    parser.add_argument('-r', '--re', choices=['C','D'], default='C')

    args = parser.parse_args()

    #Variable definitions

    if args.id == "A":
        print("A")
        function_1()
    elif args.id == "B":
        print('B')
        function_2()
    if args.re == "C":
        print('C')
    if args.re == "D":
        print('D')

如果B

import os
os.system("python3 stack37557027_A.py -i A -r C")

然后运行A并显示

A
function 1
C

使用main块,所有import stack375570237_A都会导入2个可以运行的函数,其中包含

stack375570237_A.function_A()

如果不清楚,请重读有关if __name__ == "__main__":目的的文档以及运行脚本和导入模块之间的区别。这是重要的基础Python。

使用@ atline的建议:

import subprocess

p = subprocess.Popen("python3 stack37557027_A.py -i A -r C",
                     shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

(stdoutput, erroutput) = p.communicate()
print(stdoutput)
#print(erroutput)

显示为:

b'A\nfunction 1\nC\n'
#None

同样的事情,但包裹为bytestring。

请注意,在这两种情况下,我都使用一个字符串调用脚本,该字符串包含文件名和参数。

p = subprocess.Popen(["python3", "stack37557027_A.py", "-i", "A", "-r", "C"],
                 stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

这也有效。 shell不再是True,而是使用字符串列表。

您可能需要查看subprocess的文档。 https://pymotw.com/2/subprocess/

=====================

您更新的目标是:

  

,我需要运行script_A,然后传递一个字典D,即计算的字典D(从A输出)传递给B. T

这个问题是到目前为止使用的方法只是将字符串显示为stdout,或者将字符串返回给调用者(来自stdout)。它们不像字典那样返回Python对象。

A中的哪个字典正在制作中?它如何取决于argparse选项?

让我们改变A所以身体中的一个函数产生一个字典

def function_1(id, re):
    print('function 1')
    return {'id':id, 're':re}

并使用(在'if 名称'块中)调用它:

args = parser.parse_args()
print(function_1(args.id, args.re))

结果类似于

1659:~/mypy$ python3 stack37557027_A.py 
function 1
{'re': 'C', 'id': 'A'}

脚本B也可以生成此字典的字符串显示

1659:~/mypy$ python3 stack37557027_B.py
b"function 1\n{'re': 'C', 'id': 'A'}\n"

现在,如果在B我做

import stack37557027_A as A
print(A.function_1('AA','BB'))

我得到了

{'id': 'AA', 're': 'BB'}

因此,如果所有操作都是A的主体,而if __name__块就像argparse解析和委派一样,我可以通过导入使用A中的函数,然后返回字典(或者那些函数产生的对象)。换句话说,我不需要调用A作为子进程或系统进程。

如果你确实需要将A作为一个单独的进程运行,并且仍然返回Python对象,我认为你可以使用multiprocessing

https://docs.python.org/2/library/multiprocessing.html#exchanging-objects-between-processes

https://pymotw.com/2/multiprocessing/basics.html

答案 2 :(得分:0)

版本3几乎是正确的。虽然您的示例中有很多遗漏'",但我不确定您的代码是否适合您...

from subprocess import call

# you need pass the name + all the arguments as a vector here 
process = call(["script_A.py", "-i", "A", "-r", "C"])

#Other stuff that script B does

如果要捕获输出,请使用Popen代替call

from subprocess import call, Popen

# you need pass the name + all the arguments as a vector here 
process = Popen(["script_A.py", "-i", "A", "-r", "C"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

output = process.communicate()  # let it run until finished

print output[0]  # stdout
print output[1]  # stderr
#Other stuff that script B does