为什么process.communicate()返回NoneType的元组?

时间:2017-07-13 20:42:10

标签: python popen

在程序下方,启动子流程并通过管道进行通信,

import json
import math
import subprocess
import sys
import time

if __name__ == '__main__':
    with open(sys.argv[1], 'r') as f:
        websites = f.read().splitlines()
    numberOfProcesses = int(sys.argv[2])
    perProcess = math.ceil(len(websites) / numberOfProcesses)
    for i in range(numberOfProcesses):
        sites = websites[i*perProcess:(i+1)*perProcess]
        with open("/tmp/list-{}.txt".format(i), "w") as f:
            f.write("\n".join(sites))
    t0 = time.time()
    processes = []
    for i in range(numberOfProcesses):
        p = subprocess.Popen(
            ["python3.6", "naive-checker.py", "/tmp/list-{}.txt".format(i)]
        )
        processes.append(p)
    # Gather the results
    for process in processes:
        result = process.communicate()
        print('result:',result)
    t1=time.time()
    print("Total time getting website status took {0:1f} seconds", format(t1-t0))

result显示(None, None)而不是(stdout, stderr),其中每个子流程都是,

import json
import requests
import sys
import time


def website_statuses(websites):
    statuses = {}
    for website in websites:
        response = requests.get(website)
        status = response.status_code
        if not statuses.get(status):
            statuses[status] = 0
        statuses[status] += 1
    return statuses


if __name__ == '__main__':
    with open(sys.argv[1], 'r') as f:
        websites = f.read().splitlines()
    t0 = time.time()
    print('From this subprocess, status code: ', json.dumps(website_statuses(websites)))
    t1 = time.time()
    print("For this subprocess, getting website statuses took {0:.1f} seconds".format(t1-t0))

list.txt是网站文件。

输出:

$ python3.6 dummy.py list.txt 3
 From this subprocess, status code:  {"200": 11}
 For this subprocess, getting website statuses took 5.3 seconds
 From this subprocess, status code:  {"200": 9}
 For this subprocess, getting website statuses took 6.8 seconds
 From this subprocess, status code:  {"200": 11}
 For this subprocess, getting website statuses took 9.8 seconds
 result: (None, None)
 result: (None, None)
 result: (None, None)
 Total time getting website status took {0:1f} seconds 10.265882730484009
$

问题:

为什么result显示NoneType的元组?

2 个答案:

答案 0 :(得分:3)

你应该看看the documentation

  

communicate()返回元组(stdout_data, stderr_data)。如果以文本模式打开流,则数据将是字符串;否则,字节。

     

请注意,如果要将数据发送到进程的stdin,则需要使用Popen创建stdin=PIPE对象。同样,要在结果元组中获取None以外的任何内容,您还需要提供stdout=PIPE和/或stderr=PIPE

由于您在创建Popen对象时未指定任何输出管道,因此在调用None时返回的值为communicate()两个。

您可以尝试使用以下方法修复它:

p = subprocess.Popen(
    ["python3.6", "naive-checker.py", "/tmp/list-{}.txt".format(i)],
     stdout=subprocess.PIPE, stderr=subprocess.PIPE
)

答案 1 :(得分:0)

来自Popen.communicate文档:

  

同样,要在结果元组中获取None以外的任何内容,您还需要提供stdout=PIPE和/或stderr=PIPE