str.format_map(mapping)和str.format有什么区别

N R*_*awa 10 python string string-formatting python-3.x

我不明白这个str.format_map(mapping)方法.我只知道它与str.format(*args, **kwargs)方法类似,你也可以传递字典作为参数(请参阅我的例子).例:

print ("Test: argument1={arg1} and argument2={arg2}".format_map({'arg1':"Hello",'arg2':123}))
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释str.format_map(mapping)str.format(*args, **kwargs)方法之间的区别,为什么我需要这个str.format_map(mapping) 方法?

kin*_*all 14

str.format(**kwargs)在调用过程中创建一个新的字典.str.format_map(kwargs)才不是.除了稍快一些之外,还str.format_map()允许您使用dict具有特殊行为的子类(或实现映射的其他对象),例如优雅地处理缺失的键.当项目被复制到新词典时,这种特殊行为将会丢失.

请参阅:https://docs.python.org/3/library/stdtypes.html#str.format_map

  • 奇怪的是,在`**kwargs`处理中实现`format_map`和edge case所涉及的变化组合意味着`str.format(**kwargs)`[实际上*将*通过`__missing__`传递`dict`子类方法或覆盖`__getitem__`行为并使用他们的行为](http://ideone.com/Pwi54a).我相信所有支持`format_map`的Python版本都是如此.不过,这是一个你不应该依赖的实现细节.另外,[只有`format_map`支持非dict-subclasses](http://ideone.com/TXjPyX). (2认同)
  • 自从我发表上述评论以来,[`**kwargs` 处理错误已修复](https://bugs.python.org/issue18531)。一个足够最新的 Python 将再次不会在 `str.format(**kwargs)` 中传递 dict 子类。 (2认同)

Den*_*nis 7

这是你不能做的另一件事.format(**kwargs)

>>> class UserMap:
    def __getitem__(self, key):
        return input(f"Enter a {key}: ")

>>> mad_lib = "I like to {verb} {plural noun} and {plural noun}.".format_map(UserMap())
Enter a verb: smell
Enter a plural noun: oranges
Enter a plural noun: pythons
>>> mad_lib
'I like to smell oranges and pythons.'
Run Code Online (Sandbox Code Playgroud)

调用.format(**UserMap())甚至不起作用,因为为了将 解压**kwargs到字典中,Python 需要知道映射中的所有键是什么,而这甚至没有定义。

另一个:

>>> class NumberSquarer:
    def __getitem__(self, key):
        return str(int(key.lstrip('n'))**2)

    
>>> "{n17} is a big number, but {n20} is even bigger.".format_map(NumberSquarer())
'289 is a big number, but 400 is even bigger.'
Run Code Online (Sandbox Code Playgroud)

**NumberSquarer()因为它有无限多个钥匙,所以不可能打开包装!