首页 文章

从另一个python脚本运行python脚本,传入args [duplicate]

提问于
浏览
244

这个问题在这里已有答案:

我想从另一个Python脚本运行Python脚本 . 我想传递变量,就像我使用命令行一样 .

例如,我将运行我的第一个脚本,它将迭代值列表(0,1,2,3)并将它们传递给第二个脚本 script2.py 0 然后 script2.py 1 等 .

我找到了SO 1186789这是一个类似的问题,但ars 's answer calls a function, where as I want to run the whole script not just a function, and balpha'的答案调用脚本但没有args . 我将其改为以下类似的测试:

execfile("script2.py 1")

但它没有正确接受变量 . 当我打印出script2.py中的 sys.argv 时,它是对第一个脚本“['C:\script1.py']”的原始命令调用 .

我真的不想改变原始脚本(即我的例子中的script2.py),因为我不拥有它 .

我认为必须有办法做到这一点,我很困惑你是怎么做到的 .

7 回答

  • 32

    尝试使用os.system

    os.system("script2.py 1")
    

    execfile 是不同的,因为它被设计为在当前执行上下文中运行一系列Python语句 . 这就是 sys.argv 没有为你改变的原因 .

  • 3

    这本身就是错误的做法 . 如果从另一个Python脚本运行Python脚本,则应通过Python而不是通过操作系统进行通信:

    import script1
    

    在理想的世界中,您可以直接调用 script1 中的函数:

    for i in range(whatever):
        script1.some_function(i)
    

    如有必要,你可以破解 sys.argv . 有's a neat way of doing this using a context manager to ensure that you don' t进行任何永久性更改 .

    import contextlib
    @contextlib.contextmanager
    def redirect_argv(num):
        sys._argv = sys.argv[:]
        sys.argv=[str(num)]
        yield
        sys.argv = sys._argv
    
    with redirect_argv(1):
        print(sys.argv)
    

    我认为这比将所有数据传递给操作系统更好;那太傻了 .

  • 84

    理想情况下,您要运行的Python脚本将使用接近结尾的代码进行设置:

    def main(arg1, arg2, etc):
        # do whatever the script does
    
    
    if __name__ == "__main__":
        main(sys.argv[1], sys.argv[2], sys.argv[3])
    

    换句话说,如果从命令行调用模块,它会解析命令行选项,然后调用另一个函数 main() 来执行实际工作 . (实际的参数会有所不同,解析可能会更复杂 . )

    但是,如果要从另一个Python脚本调用这样的脚本,则可以直接调用 import 并直接调用 modulename.main() ,而不是通过操作系统 .

    os.system 会起作用,但它是环形交叉(阅读"slow")的方式,因为你每次都没有葡萄干开始一个全新的Python解释程序 .

  • 76

    子过程模块:
    http://docs.python.org/dev/library/subprocess.html#using-the-subprocess-module

    import subprocess
    subprocess.Popen("script2.py 1", shell=True)
    

    有了这个,你还可以重定向stdin,stdout和stderr .

  • 37

    我认为好的做法可能是这样的;

    import subprocess
    cmd = 'python script.py'
    
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
    out, err = p.communicate() 
    result = out.split('\n')
    for lin in result:
        if not lin.startswith('#'):
            print(lin)
    

    根据文档子进程模块允许您生成新进程,连接到它们的输入/输出/错误管道,并获取它们的返回代码 . 该模块旨在替换几个较旧的模块和功能:

    os.system
    os.spawn*
    os.popen*
    popen2.*
    commands.*
    

    使用communic()而不是.stdin.write,.stdout.read或.stderr.read来避免由于任何其他OS管道缓冲区填满和阻塞子进程而导致的死锁 . Read Here

  • 25
    import subprocess
    subprocess.call(" python script2.py 1", shell=True)
    
  • 267

    如果os.system isn 't powerful enough for you, there' s the subprocess module .

相关问题