6

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

'{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()raises KeyError。我什至实施__contains__return True,但仍然KeyError

所以看起来这**不仅仅是调用__getitem__传入的对象。有谁知道如何解决这个问题?

4

4 回答 4

6

在 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需要 3 个参数:格式字符串、位置字段序列和关键字字段映射。由于不需要位置字段,我使用了一个空的 tuple ()

于 2011-11-21T22:14:43.890 回答
5

Python 3.2+:

'{Thing1} and {other_thing}'.format_map(my_mapping)
于 2011-11-21T21:24:07.313 回答
2

这可能有点死灵,但我最近遇到了这个问题,这个 SO question 是第一个结果。我对使用不满意string.Formatter,并希望它能够正常工作 (TM)

如果您keys()为您的类以及 实现一个函数__getitem__(),那么**my_mapping将起作用。

IE:

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 的位置,并且密钥集很大,那么一种可能的方法是不生成完整的密钥集,而是生成较小的子集。当然,这只有在您知道您只需要格式化一个小子集时才有效。

IE:

class Mapping(object):
  ...
  def keys(self):
    return ['Thing1','other_thing', 'Thing2']
于 2014-10-27T18:41:12.463 回答
1

这是我能想到的最好的:

如果你有一个自定义映射对象,你想将它传递给一个接受关键字参数的函数,那么它必须有一组键(可能是动态生成的,但它必须是一个有限集),并且它必须能够以某种方式映射这些键。因此,如果您可以假设它将有一个__iter__来获取密钥,并且__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)

然后我们可以通过制作一个 dict 来传递它:

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

导致:

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

显然这一定是它的完成方式......即使你传入一个派生自 的对象dict,该函数仍然有一个dict用于 kwargs 的:

class Me(dict): pass

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

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

因为听起来你想做一些事情,比如根据键是什么来返回一个值,而不考虑一组特定的键,所以你似乎不能使用这个format函数。

于 2011-11-21T22:50:20.317 回答