代码之家  ›  专栏  ›  技术社区  ›  CSJ

python数据类型转换在打印和写入时的行为不同

  •  -2
  • CSJ  · 技术社区  · 6 年前

    代码片段如下(如果某个键不在dict中,我想存储整个dict内容,否则只存储键的值)

    result = {
        'stdout': 'some output'
    }
    
    print('result: %s' % result['stderr'] if 'stderr' in result else result)
    
    with open('result.txt', 'w') as f:
        f.write('result: %s\n' % result['stderr'] if 'stderr' in result else result)
    

    在这里,我试图记录一些消息使用 write stderr result ,如果是,则使用它(字符串),否则记录dict 结果

    print 它工作得很好,但失败了

    TypeError:write()参数必须是str,而不是dict

    因为我用 %s str(result)

    为什么它失败了 ?

    2 回复  |  直到 6 年前
        1
  •  4
  •   Mikhail Burshteyn    6 年前

    代码中的问题是“%”的优先级高于条件运算符。因为这个,

    'result: %s' % result['stderr'] if 'stderr' in result else result
    

    相当于

    ('result: %s' % result['stderr']) if 'stderr' in result else result
    

    所以,如果 'stderr' not in result ,此表达式将返回 result ,这是一条格言。现在, print() 会打印任何东西,但是 write 需要一个字符串参数,当收到dict时失败。

    您想要的结果是:

    'result: %s' % (result['stderr'] if 'stderr' in result else result)
    

    您的代码应修改如下:

    print('result: %s' % (result['stderr'] if 'stderr' in result else result))
    
    with open('result.txt', 'w') as f:
        f.write('result: %s\n' % (result['stderr'] if 'stderr' in result else result))
    
        2
  •  2
  •   Leo K    6 年前

    您看到这个错误是因为如果'result'不包含'stdout',您拥有的Python表达式将产生dictionary对象。这可能是 print

    问题在于表达式中操作的优先级:如果。。。否则就不能紧紧地绑在一起。

    我怀疑你想要的是:

    f.write('result: %s\n' % (result['stderr'] if 'stderr' in result else result) )
    

    注意括号。