【问题标题】:subprocess.Popen(..).communicate(..) throw away data at random when used with graphviz!subprocess.Popen(..).communicate(..) 与graphviz一起使用时随机丢弃数据!
【发布时间】:2011-01-15 23:14:22
【问题描述】:

我正在使用 graphviz 的 dot 为 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)

发生的事情是 dot 程序抛出如下错误:

    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 触发的,与从 shell 中使用

【问题讨论】:

    标签: python pipe subprocess graphviz popen


    【解决方案1】:

    听起来你应该这样做:

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

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

    最重要的是,没有理由在那个 sn-p 中使用 shell=True,也没有理由将 unicode 文字传递给 subprocess.Popen 一个特别好的主意(它只是被编码为 ASCII。)反斜杠在结尾是不必要的——Python 知道该行是继续的,因为您有一个尚未关闭的左括号。所以,使用:

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

    【讨论】:

    • 谢谢托马斯!那成功了。男孩,我觉得自己很愚蠢,我花了 5 个小时“调试”一个微不足道的 unicode 问题 :-(。也感谢风格提示。对不起,如果我的蹩脚代码造成了人身伤害!;-)
    • 我收到“UnicodeEncodeError: 'ascii' codec can't encode characters in position 29-31: ordinal not in range(128)”。任何想法? tia 顺便说一句,它在 Windows 上是 2.6:
    猜你喜欢
    • 1970-01-01
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    • 2011-05-16
    • 1970-01-01
    • 1970-01-01
    • 2016-08-04
    • 1970-01-01
    相关资源
    最近更新 更多