我可以使用动态映射解包Python中的关键字参数吗?
长话短说,我想用任意名称的参数来调用格式化函数,这样可以进行查找。
'{Thing1} and {other_thing}'.format(**my_mapping)
我尝试像这样实现我的映射(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
错误。我甚至实现了 __contains__
方法,让它总是返回真(True),但还是出现了 KeyError
。
所以看起来 **
不是简单地在传入的对象上调用 __getitem__
方法。有没有人知道该怎么解决这个问题?
4 个回答
这可能有点像复活死去的内容,但我最近遇到了这个问题,而这个StackOverflow的问题是我找到的第一个结果。我对使用 string.Formatter
不太满意,想要它能够直接工作 (TM)。
如果你为你的类实现一个 keys()
函数和 __getitem__()
方法,那么 **my_mapping
就能正常工作。
也就是说:
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']
将会得到一个成功的映射,可以与 .format
一起使用。
显然(虽然我并没有实际查看 str.format
的源代码),它似乎是使用 keys()
来获取一个键的列表,然后将字符串中给出的标识符映射到这些键上,最后使用 __getitem__()
来获取指定的值。
希望这对你有帮助。
编辑:
如果你处于 @aaron-mcmillin 的情况,并且键的集合很大,那么一个可能的方法是不要生成完整的键集,而是生成一个较小的子集。当然,这只有在你知道只需要格式化一个小子集时才有效。
也就是说:
class Mapping(object):
...
def keys(self):
return ['Thing1','other_thing', 'Thing2']
Python 3.2及以上版本:
'{Thing1} and {other_thing}'.format_map(my_mapping)
在Python 2中,你可以使用 string.Formatter
类来做到这一点。
>>> 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
这个函数需要三个参数:格式字符串、位置字段的序列和关键字字段的映射。因为不需要位置字段,所以我用了一个空的元组 ()
。