如何将从子进程传递到父进程的列表添加到python中已存在的列表

时间:2015-07-06 16:16:26

标签: python list subprocess output

我将一个列表从subprocess传递给父进程,在父进程中我想将其添加到现有列表中。我这样做了:

subprocess_script.py:

def func():

    list = []
    list.append('1')
    list.append('2')

    print'Testing the list passing'
    print '>>> list:',list

if __name__ == '__main__':
     func()

parent_script.py:

list1 = []
list1.append('a')
list1.append('b')
ret = subprocess.Popen([sys.executable,"/Users/user1/home/subprocess_script.py"],stdout=subprocess.PIPE)
ret.wait()

return_code = ret.returncode
out, err = ret.communicate()
if out is not None:
        for line in out.splitlines():

            if not line.startswith('>>>'):
                continue
            value = line.split(':',1)[1].lstrip()
            list1.extend(value)
print 'Final List: ',list1

但是当我执行此操作时,我没有得到所需的输出。我想要的最终列表应该是:['a','b','1','2']。但我得到['a', 'b', '[', "'", '1', "'", ',', ' ', "'", '2', "'", ']']这是错误的。我在这里做错了什么?

3 个答案:

答案 0 :(得分:2)

问题是,在splitlstrip来电之后,value 仍然是字符串,而不是列表。您可以停止包含pdb.set_trace行的脚本并按如下方式进行检查:

if not line.startswith('>>>'):
    continue
import pdb; pdb.set_trace()
value = line.split(':', 1)[1].lstrip()
list1.extend(value)

然后运行代码:

❯ python main.py
> /private/tmp/example/main.py(19)<module>()
-> value = line.split(':', 1)[1].lstrip()
(Pdb) line
">>> list: ['1', '2']"
(Pdb) line.split(':', 1)[1].lstrip()
"['1', '2']"

您可以使用ast.literal_eval函数将该字符串计算到Python列表中,如下所示:

(Pdb) import ast
(Pdb) ast.literal_eval(line.split(':', 1)[1].lstrip())
['1', '2']

现在可以使用此值扩展list1

来自the Python 2.7 documentation

  

ast.literal_eval(node_or_string)

     

安全地评估表达式节点或包含Python文字或容器显示的Unicode或Latin-1编码字符串。提供的字符串或节点可能只包含以下Python文字结构:字符串,数字,元组,列表,dicts,布尔值和None。

     

这可以用于安全地评估包含来自不受信任来源的Python值的字符串,而无需自己解析值。它无法评估任意复杂的表达式,例如涉及运算符或索引。

答案 1 :(得分:1)

你做错了。

当你这样做时 - print '>>> list:',list。它会打印 -

>>> list: [1, 2]

当你做 - value = line.split(':',1)[1].lstrip()时,值将成为字符串 -

'[1, 2]'

当使用list1扩展value时,值中的每个字符都将作为list1中的新元素添加(因为它会迭代字符串的每个元素,每个元素都是字符并将它们添加到list1)。

创建值时,您要删除第一个[以及落后的],然后根据,拆分它们。

示例代码 -

value = line.split(':',1)[1].lstrip().lstrip('[').rstrip(']').replace("'",'').replace(" ",'').split(',')

上面的代码是一个非常大的黑客,更好的是使用ast.literal_eval作为@logc在他的回答中提到 -

import ast
value = ast.literal_eval(line.split(":",1)[1].lstrip())

但请注意,ast.literal_eval会评估表达式并返回结果,您应该谨慎使用。

答案 2 :(得分:1)

使用标准序列化数据格式,如JSON:

<强> script.py

import sys
import os
import subprocess
import json

list1 = []
list1.append('a')
list1.append('b')
ret = subprocess.Popen([sys.executable, os.path.join(os.getcwd(), "script.py")], stdout=subprocess.PIPE)
ret.wait()

return_code = ret.returncode
out, err = ret.communicate()
line = next(line for line in out.splitlines())
value = json.loads(line)  ## <-- `loads` loads from a string
list1.extend(map(str, value))
print 'Final List: ', list1

<强> main.py

map(str, value)

json.dumps只是审美:它有一个统一的列表,因为list1默认会生成Unicode字符串,而你之前的{{1}}元素不是Unicode字符串。< / p>

此外,我删除了代码的整个标题打印和跳过部分。你只是让他们的生活变得更加艰难:)