Python 解包进行字符串格式化时未使用的dict键

Python 解包进行字符串格式化时未使用的dict键,python,Python,有没有一种方法可以查看字典中的哪些键在解包进行字符串格式化时没有被使用 例如: >format_dict={'first':'think','second':'am','third':'never'} >格式_str='I{first},因此I{second}' >打印(格式打印格式(**格式打印)) 我思故我在 但在这种情况下,我真正想知道的是,从未使用过键third。有没有办法获取此信息?您可以从模板字符串中解析“键”,然后使用集合操作(集合减法)检查哪些键在字典中,哪些键不在模板字符串中

有没有一种方法可以查看字典中的哪些键在解包进行字符串格式化时没有被使用

例如:

>format_dict={'first':'think','second':'am','third':'never'}
>格式_str='I{first},因此I{second}'
>打印(格式打印格式(**格式打印))
我思故我在
但在这种情况下,我真正想知道的是,从未使用过键
third
。有没有办法获取此信息?

您可以从模板字符串中解析“键”,然后使用集合操作(集合减法)检查哪些键在字典中,哪些键不在模板字符串中:

import re

format_dict = {'first': 'think', 'second': 'am', 'third': 'never'}
format_str = 'I {first}, therefore I {second}'

not_used = format_dict.keys() - set(re.findall(r'{(.+?)}', format_str))
print(not_used)
输出

{'third'}
{'third'}
I think, therefore I am
可以通过子类化
UserString
将其烘焙为
.format

from collections import UserString
import re

class MyString(UserString):
    def format(self, *args, **kwargs):
        print(kwargs.keys() - set(re.findall(r'{(.+?)}', str(self))))
        return super().format(*args, **kwargs)

format_str = MyString('I {first}, therefore I {second}')

format_dict = {'first': 'think', 'second': 'am', 'third': 'never'}
print(format_str.format(**format_dict))
输出

{'third'}
{'third'}
I think, therefore I am
如果您打算大量使用此项,则有必要重新编译正则表达式。

您可以从模板字符串中解析“键”,然后使用集合操作(集合减法)检查哪些键在字典中,哪些键不在模板字符串中:

import re

format_dict = {'first': 'think', 'second': 'am', 'third': 'never'}
format_str = 'I {first}, therefore I {second}'

not_used = format_dict.keys() - set(re.findall(r'{(.+?)}', format_str))
print(not_used)
输出

{'third'}
{'third'}
I think, therefore I am
可以通过子类化
UserString
将其烘焙为
.format

from collections import UserString
import re

class MyString(UserString):
    def format(self, *args, **kwargs):
        print(kwargs.keys() - set(re.findall(r'{(.+?)}', str(self))))
        return super().format(*args, **kwargs)

format_str = MyString('I {first}, therefore I {second}')

format_dict = {'first': 'think', 'second': 'am', 'third': 'never'}
print(format_str.format(**format_dict))
输出

{'third'}
{'third'}
I think, therefore I am

如果您打算大量使用此函数,则有必要重新编译正则表达式。

您可以在执行格式化之前对照字符串检查
dict
中的键值

>>>unused = [v for k,v in format_dict.items() if k not in format_str]
>>>print(unused)
['never']

可能不太适合冲突,但这取决于您的字符串。

在执行格式化之前,您可以对照字符串检查
dict
中的键值

>>>unused = [v for k,v in format_dict.items() if k not in format_str]
>>>print(unused)
['never']

可能不太适合冲突,但这取决于您的字符串。

这里不需要摆弄正则表达式,请使用官方的
string.Formatter.parse
():

印刷品:

{'third'}

这里不需要修改正则表达式,请使用官方的
string.Formatter.parse
():

印刷品:

{'third'}

如果不以某种方式对
.format
进行黑客攻击,或者手动解析模板字符串并将其与dict键进行比较,您为什么需要这些信息?@chepner我们有一个隐藏的可用参数列表,可将其格式化为sql查询模板。我想提醒用户,他们的某些输入是不允许的。然后将对
格式的调用包装到一个执行检查的函数中。顺便说一句,您不应该首先使用
str.format
来构建SQL查询。这不是没有以某种方式破解
.format
,或者手动解析模板字符串并将其与dict键进行比较为什么需要这些信息?@chepner我们有一个隐藏的可用参数列表,可以将其格式化为sql查询模板。我想提醒用户,他们的某些输入是不允许的。然后将对
format
的调用包装到执行检查的函数中。顺便说一句,您不应该首先使用
str.format
来构建SQL查询。您添加的子类化是一个很好的方法!您添加的子类化是一个很好的方法!这种方法比由DeepSpace发布的带有正则表达式的解决方案更有效吗?@asikorski我想说更正确的方法,因为它使用的方法与
.format()
相同。可能会有转义的
\{\}
等…这种方法比使用由DeepSpace发布的正则表达式的解决方案更有效吗?@asikorski我想说更正确的方法,因为它使用的方法与
.format()
相同。可能有转义的
\{\}
等。。。