【问题标题】:Python: To Subprocess or Not To Subprocess into Another Python Subprocess?Python:子进程还是不子进程到另一个 Python 子进程?
【发布时间】:2014-02-27 23:45:11
【问题描述】:

编辑了一个原始问题/帖子以避免重复,但尚未达到目的。

我想知道从已经运行的脚本中子进程到另一个 Python 脚本的执行是否是一种常见的做法?

稍后编辑:

如果 subprocesss.Pipe() 用于运行一些外部进程(例如:其他应用程序或系统命令),我会说它是一个选择。 “虚拟”子处理当前正在运行的脚本的方法(或函数)多线程是完全有意义的。

【问题讨论】:

  • 谢谢 Joran,我刚刚编辑了 OP。
  • 您能否具体说明您的代码存在哪些问题?它会产生任何错误吗?对你的目的来说太慢了吗? (我在代码中看到了多个问题,但如果它对您有用,那么这是codereview.stackexchange.com 的问题)
  • 我想知道通过 subprocess.popen() 直接调用 python 可执行文件来对另一个 python 进程进行子处理是否是一种正确的方法。或者是否应该避免。如果应该避免,那为什么。
  • 你试过exec函数吗?

标签: python cmd subprocess


【解决方案1】:

从不同文件运行 Python 代码的常用方法是将其作为模块导入并直接使用其中定义的对象:

# assert "/filepath/to" in sys.path
import your_script # import module defined in your_script.py

your_script.copyfile(srcfile, dest)

要在多个进程中运行 Python 代码,您可以使用 multiprocessing 模块:

from multiprocessing import Pool
import your_script

def copyfile(srcfile):
    try:
        dest = ... srcfile ...
        your_script.copyfile(srcfile, dest)
    except Exception as e:
        return srcfile, None, str(e)
    else: 
        return srcfile, dest, None # no errors

def main():
    sources = [...]
    pool = Pool(20) # don't copy more that 20 files at once
    results = pool.map(copyfile, sources)

if __name__ == "__main__":
   main()

要使用线程而不是进程,只需更改导入:

from multiprocessing.dummy import Pool # use threads

目前尚不清楚并行 IO 操作可能会对性能产生什么影响。

【讨论】:

    【解决方案2】:

    这是一个工作代码,它利用多处理和子进程的 popen() 将文件从源复制到目标。


    import os, sys, subprocess
    from multiprocessing import Pool
    
    
    def copyUsingSubprocess(source):
    
        folder=os.path.dirname(source)
        srcFileName, srcFileExt=os.path.splitext(os.path.basename(source))
        destFilename=srcFileName+'_dest'+srcFileExt
    
        dest='/'.join([folder,destFilename])
    
        cmd=['cp', source, dest]
    
        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    
    
    sources = ['/Volumes/files/a.data','/Volumes/files/b.data',
                '/Volumes/files/c.data','/Volumes/files/d.data',
                '/Volumes/files/e.data','/Volumes/files/f.data']
    
    pool = Pool(20)
    results = pool.map(copyUsingSubprocess, sources)
    

    下面是类似的代码。它也使用 subprocess.popen() 来执行文件复制。但它无需调用多处理的 Pool.map() 方法即可完成。

    import os, sys, subprocess
    
    def copyUsingSubprocess(cmd):
        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    
    sources = ['/Volumes/files/a.data','/Volumes/files/b.data',
                '/Volumes/files/c.data','/Volumes/files/d.data',
                '/Volumes/files/e.data','/Volumes/files/f.data']
    
    for source in sources:
        folder=os.path.dirname(source)
        srcFileName, srcFileExt=os.path.splitext(os.path.basename(source))
    
    
        destFilename=srcFileName+'_dest'+srcFileExt
        dest='/'.join([folder,destFilename])
    
    
        cmd=['cp', source, dest]
    
        copyUsingSubprocess(cmd) 
    

    【讨论】:

    • 从不同的进程调用Popen() 是没有意义的。 Popen 不等待子进程完成。它会在子进程启动后立即返回。
    猜你喜欢
    • 1970-01-01
    • 2022-01-06
    • 2014-09-19
    • 1970-01-01
    • 2022-06-14
    • 1970-01-01
    • 1970-01-01
    • 2010-11-17
    • 1970-01-01
    相关资源
    最近更新 更多