我可以使用动态映射来解压Python中的关键字参数吗?

我可以使用动态映射来解压Python中的关键字参数吗?,python,keyword-argument,Python,Keyword Argument,长话短说,我想用任意命名的参数调用format,这将执行查找 '{Thing1} and {other_thing}'.format(**my_mapping) 我尝试过这样实现我的_映射: class Mapping(object): def __getitem__(self, key): return 'Proxied: %s' % key my_mapping = Mapping() 在调用my_mapping['anything']时,它会按预期工作。但当传递到forma

长话短说,我想用任意命名的参数调用format,这将执行查找

'{Thing1} and {other_thing}'.format(**my_mapping)
我尝试过这样实现我的_映射:

class Mapping(object):
  def __getitem__(self, key):
    return 'Proxied: %s' % key
my_mapping = Mapping()
在调用my_mapping['anything']时,它会按预期工作。但当传递到format()时,如上图所示,我得到:

TypeError: format() argument after ** must be a mapping, not Mapping
我尝试将
dict
子类化,而不是
object
,但现在调用
format()
,如图所示,会引发
KeyError
。我甚至实现了
\uuuu contains
return True
,但仍然
keyrerror

因此,
**
似乎不仅仅是在传入的对象上调用
\uu getitem\uu
。有人知道如何解决这个问题吗?

Python3.2+:

'{Thing1} and {other_thing}'.format_map(my_mapping)

在Python2中,可以使用
string.Formatter
class来实现这一点

>>> class Mapping(object):
...     def __getitem__(self, key):
...         return 'Proxied: %s' % key
...
>>> my_mapping = Mapping()
>>> from string import Formatter
>>> Formatter().vformat('{Thing1} and {other_thing}', (), my_mapping)
'Proxied: Thing1 and Proxied: other_thing'
>>>

vformat
接受3个参数:格式字符串、位置字段序列和关键字字段映射。由于不需要位置字段,我使用了一个空元组
()

,这是我能想到的最好方法:

如果您有一个自定义映射对象,希望将其传递给使用关键字参数的func,则该对象必须具有一组键(可以动态生成,但必须是有限集),并且必须能够以某种方式映射这些键。因此,如果您可以假设它将有一个
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
来获取密钥,并且一个
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu getitem>将成功获取这些密钥,例如:

class Me(object):
    def __init__(self):
        pass

    def __iter__(self):
        return iter(['a', 'b', 'c'])

    def __getitem__(self, key):
        return 12
假设函数是:

def myfunc(**kwargs):
    print kwargs, type(kwargs)
然后我们可以通过做一个口述来传递它:

m = Me()
myfunc(**dict((k, m[k]) for k in m))
导致:

{'a': 12, 'c': 12, 'b': 12} <type 'dict'>

由于听起来您想根据键的内容返回一个值,而没有考虑一组特定的键,因此您似乎无法使用
format
函数

这可能有点像巫术,但我最近遇到了这个问题,所以这个问题是第一个结果。我不喜欢使用
string.Formatter
,希望它能正常工作

如果您为您的类实现了
keys()
函数以及
\uu getitem\uuu()
,那么
**my\u映射将起作用

即:

在哪里

将导致使用
.format
的成功映射

显然(虽然我实际上没有查看
str.format
)的源代码,但它似乎使用
keys()
来获取一个键列表,然后将字符串中给定的标识符映射到这些键,然后使用
\uu getitem\uu()
来检索指定的值

希望这有帮助

编辑:

如果您处于@aaron mcmillin的位置,并且密钥集很大,那么一种可能的方法是不生成完整的密钥集,而是生成较小的子集。当然,只有当您知道只需要格式化一小部分时,这才有效

即:


**
无法真正使用
\uuuu getitem\uuuu
。当将参数传递给接受任何关键字参数的函数(
**kwargs
)时,它会得到哪些项?这可能与python<3.2时得到的一样好<代码>{0[Thing1]}和{0[other_thing]}。格式(my_mapping)
它至少可以工作。一般来说,不需要对自己的问题进行评论,例如,你可以更新你的问题,指定你使用Python 2.6.5,如果它是相关的,或者将你最后的评论作为答案发布(如果在几天内没有更好的结果,那么就接受它)。这正是我所需要的,但它是在python 3.2中添加的(只是查了一下)。好吧,我心目中的特定密钥集是LDAP中的所有cn,这对于提取到字典中进行一两次查找来说有点过分。@Aroncroye:是的,基本上,这个答案是说你不能用
格式
函数来做你想做的事情。太好了!这正是我所需要的。这很好,但正如我上面的评论所说,我的密钥空间是LDAP中的所有CN,每个字符串的查找次数将是最小的。因此,我并不想生成所有的密钥。在这种情况下,解决方案不适合您,但它仍然是一个完全有效(且正确)的答案。它只提供一个
格式的类所能提供的标准python魔术函数。我完全理解,如果您有一个大的密钥集(并且如果您的LDAP服务器通过网络连接),您可能不想花费生成密钥集所需的周期。
class Me(dict): pass

m = Me()
print type(m) #prints <class '__Main__.Me'>

def myfunc(**kwargs):
    print type(kwargs)
myfunc(**m) #prints <type 'dict'>
class Mapping(object):

  def __getitem__(self, key):
    return 'Proxied: %s' % key

  def keys(self):
    return proxy.keys()
>>> my_mapping = Mapping()
>>> my_mapping.keys()
['Thing1','other_thing',...,'Thing2']
class Mapping(object):
  ...
  def keys(self):
    return ['Thing1','other_thing', 'Thing2']