我将一个列表从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', "'", ']']
这是错误的。我在这里做错了什么?
答案 0 :(得分:2)
问题是,在split
和lstrip
来电之后,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>
此外,我删除了代码的整个标题打印和跳过部分。你只是让他们的生活变得更加艰难:)