我可以使用动态映射来解压Python中的关键字参数吗?
长话短说,我想用任意命名的参数调用format,这将执行查找我可以使用动态映射来解压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
'{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']