subprocess.Popen(..)。communication(..)在与graphviz一起使用时随机丢弃数据!

时间:2010-02-12 00:21:45

标签: python pipe subprocess graphviz popen

我使用graphviz的点为Web应用程序生成一些svg图。我用Popen打电话给dot:

    p = subprocess.Popen(u'/usr/bin/dot -Kfdp -Tsvg', shell=True,\
    stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    str = u'long-unicode-string-i-want-to-convert'
    (stdout,stderr) = p.communicate(str)

点程序抛出的错误如下:

    Error: not well-formed (invalid token) in line 1 
 ... <tr><td cellpadding="4bgcolor="#EEE8AA"> ...
in label of node n260

这个明显的错误肯定不在输入字符串中。特别是,如果我用utf-8编码将它保存到str.txt并执行

/usr/bin/dot -Kfdp -Tsvg < str.txt > myimg.svg

我得到了所需的输出。关于str的唯一“特殊”事情是它包含像丹麦øæå这样的字符。

现在我不知道该做什么。这个问题很可能出现在问题中;但它似乎肯定是由于Popen与使用&lt;来自shell,我不知道从哪里开始。任何帮助或想法,或者调用dot(除了将所有数据写入文件并调用它!)将非常感激!

1 个答案:

答案 0 :(得分:3)

听起来你应该这样做:

stdout, stderr = p.communicate(str.encode('utf-8'))

(当然,除了你不应该隐藏内置str。)Python中的unicode类型包含unicode数据,不是 UTF-8。如果你想要UTF-8,你需要对它进行显式编码。

最重要的是,没有理由在该片段中使用shell=True,也没有将unicode文字传递给subprocess.Popen是一个特别好的主意(无论如何它只是被编码为ASCII。)并且反斜杠在结束是不必要的 - Python知道这条线是继续的,因为你有一个尚未关闭的开括号。所以,使用:

p = subprocess.Popen(['/usr/bin/dot', '-Kfdp', '-Tsvg'],
    stdin=subprocess.PIPE, stdout=subprocess.PIPE)
相关问题