为什么在string.format()字典引用中不需要'?

Chr*_*ris 2 python dictionary string-formatting python-3.x

my_dic={"Vajk":"vékony","Bibi":'magas'}
my_dic['Bibi']
'magas'
Run Code Online (Sandbox Code Playgroud)

我们可以看到,我们需要'引用关键'Bibi'的价值.但是如果想在.format()中使用相同的格式,则会出现以下错误:

print("úgy érzem, hogy Bibi nagyon {0['Bibi']}".format(my_dic))
Traceback (most recent call last):

  File "<ipython-input-109-52760dad9136>", line 1, in <module>
    print("úgy érzem, hogy Bibi nagyon {0['Bibi']}".format(my_dic))

KeyError: "'Bibi'"
Run Code Online (Sandbox Code Playgroud)

我必须使用没有'的引用,然后它的工作原理.

print("úgy érzem, hogy Bibi nagyon {0[Bibi]}".format(my_dic))
úgy érzem, hogy Bibi nagyon magas
Run Code Online (Sandbox Code Playgroud)

为什么不首先工作,为什么第二个工作?它应该是相反的,首先应该工作,第二个不应该.

Mar*_*ers 5

首先,一些术语:

  • 'Bibi'是一个字符串文字,用于创建字符串值的语法.您的键是字符串,使用字符串文字可以指定其中一个键.

    你可以使用变量; 将string作为字符串赋值给变量并使用该变量从字典中获取项目:

    foo = 'Bibi'  # or read this from a file, or from a network connection
    print(my_dic[foo])  # -> magas
    
    Run Code Online (Sandbox Code Playgroud)
  • 在字符串格式中,{...}替换字段.该str.format()方法提供替换字段的值.

  • 替换字段语法中的0[Bidi]部分{...}字段名称.[...]在字段名称中使用时,它是复合字段名称(有多个部分).的[...]语法通常被称为索引.

字段名称使用的格式是刻意保持简单,只Python- 喜欢.语法被简化以限制它可以用于什么,将功能约束到通常可以安全使用的东西.

因此,如果使用带有getitem [...]索引语法的复合名称,则将名称视为字符串,但不使用引号来创建字符串.无论如何都无法传递变量名,不需要在'name'(字符串)和name(变量)之间进行对比.

换句话说,在Python表达式中,my_dic[foo]通过查找变量的值来工作foo,这与使用字符串文字的概念不同my_dic['Bidi'].但是你不能在字段名中使用变量,在str.format()操作中,使用{0[foo]}永远不会找到变量foo.

添加该功能的原始提案将其解释为:

与其他一些编程语言不同,您不能在格式字符串中嵌入任意表达式.这是设计 - 您可以使用的表达类型是故意限制的.只支持两个运营商:'.' (getattr)运算符和'[]'(getitem)运算符.允许这些操作者的原因是它们通常在非病理代码中没有副作用.

应该注意的是,在格式字符串中使用'getitem'比其常规用法更受限制.在上面的例子中,字符串'name'实际上是文字字符串'name',而不是名为'name'的变量.解析项密钥的规则非常简单.如果它以数字开头,则将其视为数字,否则将其用作字符串.

保持语法简单使模板更安全.从安全注意事项部分:

除此之外,下一个最好的方法是确保字符串格式没有副作用.由于Python的开放性,不可能保证任何非平凡的操作都具有此属性.这个PEP所做的是将格式字符串中的表达式类型限制为那些可见的副作用很少并且受到Python开发人员文化强烈反对的表达式.

允许{0[foo]}在当前范围内查找变量很容易产生副作用,而将其foo视为字符串则意味着您可以确切地知道它始终是字符串'foo'而不是其他内容.

如果您使用字符串文字而不是动态值(因此'some {} template'.format(...)而不是some_variable.format(...),并且您使用的是Python 3.6或更新版本,则可以使用格式化的字符串文字,因为您可以使用完整的Python表达式:

print(f"úgy érzem, hogy Bibi nagyon {my_dic['Bibi']}")
Run Code Online (Sandbox Code Playgroud)

f字符串中,您使用实际的Python表达式而不是字段名称,因此再次使用引号传入字符串文字.因为它们是字符串文字,所以它们在定义它们的地方进行评估,并且作为开发人员,您可以看到哪些局部变量可用,因此您可能知道如何保证其安全.