【问题标题】:Python reading string of dictionary incorrectly when using .format()使用 .format() 时 Python 错误地读取字典字符串
【发布时间】:2020-02-07 10:55:54
【问题描述】:

我正在 Python 3.6.6 中创建一个字典字符串(稍后添加到 .txt 文件中)。

当我硬编码字典的字符串时,我没有遇到任何问题:

my_string = '{"source": "s3://some_s3_bucket/random_filename.csv"} \n'
print(my_string)

输出

{“来源”:“s3://some_s3_bucket/random_filename.csv”}

但是,当我尝试用硬编码的文件路径替换变量时,Python 似乎开始假设“源”是我要替换的变量:

bucket = "some_s3_bucket"
filename = "random_filename.csv"
my_new_string = '{"source": "s3://{0}/{1}"} \n'.format(bucket, filename)
print(my_new_string)

输出

KeyError Traceback(最近一次调用最后一次) 在模块
--> 1 my_new_string = '{"source": "s3://{0}/{1}"} \n'.format(bucket, filename)
2 打印(my_new_string)

KeyError: '"source"'

我应该如何格式化这个字符串以便 Python 正确读取我的 bucketfilename 变量?

【问题讨论】:

  • 你可以简单地使用旧的格式化方式:my_new_string = '{"source": "s3://%s/%s"} \n' % (bucket, filename)

标签: python python-3.x


【解决方案1】:

format 触发花括号上的替换。您在字符串的开头有一个花括号。顺便说一句,在字段名称之后,您可以附加格式修饰符,用冒号分隔。因此,大括号和冒号之间的所有内容都被视为字段名称,并且您没有名为 "source" 的字段(连同引号)。

要输出花括号,请将其加倍:

my_new_string = '{{"source": "s3://{0}/{1}"}} \n'.format(bucket, filename)

但是 Talon 的评论是正确的,使用 json 模块比手动制作 JSON 更好,因为在一般情况下,变量的值可能需要转义。由于您将没有需要输出的大括号,您的format 问题就消失了:

import json
my_new_string = json.dumps({"source": "s3://{0}/{1}".format(bucket, filename) })

【讨论】:

  • 感谢您解释为什么我应该使用 json.dumps() 而不仅仅是附加到字符串。我改变了我的代码来做到这一点。感谢您的修复!
【解决方案2】:

您使用的是字符串格式,因此您必须使用双精度 {{ 数据 }}

In [1]: bucket = "some_s3_bucket" 
   ...: filename = "random_filename.csv" 
   ...: my_new_string = '{{"source": "s3://{0}/{1}"}} \n'.format(bucket, filename) 
   ...: print(my_new_string)                                                                                                                          
{"source": "s3://some_s3_bucket/random_filename.csv"\}

查看此处了解更多信息How can I print literal curly-brace characters in python string and also use .format on it?

【讨论】:

    【解决方案3】:

    str.format() 使用{} 字符作为要格式化的参数的占位符。您在格式字符串的开头使用了{,这导致了问题。你想要做的是使用双括号 {{}} ,它们需要被视为文字大括号而不是替换:

    my_new_string = '{{"source": "s3://{0}/{1}"}} \n'.format(bucket, filename)
    

    此外,这是生成 JSON 数据的糟糕方式(请参阅 Talon 的评论)。

    【讨论】:

      【解决方案4】:

      问题在于您那里的那些 { 和 } 字符没有指定格式化键。

      bucket = "some_s3_bucket"
      filename = "random_filename.csv"
      my_new_string = '{{"source": "s3://{0}/{1}"}} \n'.format(bucket, filename)
      print(my_new_string)
      

      【讨论】:

        【解决方案5】:

        问题在于花括号使用:

        my_new_string = '{{"source": "s3://{}/{}"}}'.format(bucket, filename)
        
        

        输出了这个

        {“来源”:“s3://some_s3_bucket/random_filename.csv”}

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-07-02
          • 2012-09-30
          • 2016-10-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多