python 字符串格式 抑制/静默 keyerror/indexerror
有没有一种方法可以使用 python string.format ,以便在缺少索引时不会引发异常,而是插入空字符串。
result = "i am an {error} example string {error2}".format(hello=2,error2="success")
这里,结果应该是:
"i am an example string success"
现在,python 抛出一个关键错误并停止格式化。有可能改变这种行为吗?
谢谢
编辑:
存在 Template.safe_substitute (即使保留模式完整而不是插入空字符串),但对于 string.format 不能有类似的东西
所需的行为将类似于 php 中的字符串替换。
class Formatter(string.Formatter):
def get_value(self,key,args,kwargs):
try:
if hasattr(key,"__mod__"):
return args[key]
else:
return kwargs[key]
except:
return ""
这似乎提供了所需的行为。
Is there a way to use python string.format such that no exception is thrown when an index is missing, instead an empty string is inserted.
result = "i am an {error} example string {error2}".format(hello=2,error2="success")
here,result should be :
"i am an example string success"
Right now, python throws a keyerror and stops formatting. Is it possible to change this behavior ?
Thanks
Edit:
There exists Template.safe_substitute (even that leaves the pattern intact instead of inserting an empty string) , but couldn't something similar for string.format
The desired behavior would be similar to string substitution in php.
class Formatter(string.Formatter):
def get_value(self,key,args,kwargs):
try:
if hasattr(key,"__mod__"):
return args[key]
else:
return kwargs[key]
except:
return ""
This seems to provide the desired behavior.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
格式映射中字符串的官方解决方案(Python 3 Docs)是子类化
dict
类并定义魔术方法__missing__()
。每当缺少键时就会调用此方法,并且它返回的内容将用于字符串格式化:编辑:第二个 print() 在 Python 3.5.3 中有效,但在例如 3.7 中无效.2:
KeyError: 'bar'
被引发,我找不到捕获它的方法。经过一些实验,我发现 Python 的行为有所不同。在 v3.5.3 中,调用成功的是
__getitem__(self, "foo")
,而__getitem__(self, "bar")
则找不到密钥"bar"
,因此它调用__missing__(self, "bar")
来处理丢失的键,而不抛出 KeyError。在 v3.7.2 中,内部调用 __getattribute__(self, "keys")。内置的keys()
方法用于返回键上的迭代器,该迭代器产生“foo”,__getitem__("foo")
成功,则迭代器为筋疲力尽的。对于格式字符串中的{bar}
,没有键"bar"
。__getitem__()
和__missing_()
不会被调用来处理这种情况。相反,会抛出 KeyError。我不知道如何才能抓住它(如果有的话)。在 Python 3.2+ 中,您应该使用
format_map()
代替(另请参阅 Python Bug Tracker - 问题 6081):如果您想保留占位符,您可以这样做:
如您所见,
format_map()
确实调用 <代码>__missing__()。以下似乎是最兼容的解决方案,因为它也适用于包括 2.x 在内的旧版 Python 版本(我测试了 v2.7.15):
保持占位符原样包括格式规范(例如
{bar:<15}
) 需要对格式化程序进行子类化:请注意,占位符索引不会更改(
{1}
保留在字符串中,而没有{0 }
),为了替换{1}
,您需要传递一个包含任何奇数第一个元素的数组以及您想要替换剩余占位符作为第二个元素的数组(例如[无,“实际”]
)。您还可以使用位置参数和命名参数调用
format()
方法:The official solution (Python 3 Docs) for strings in format mappings is to subclass the
dict
class and to define the magic-method__missing__()
. This method is called whenever a key is missing, and what it returns is used for the string formatting instead:Edit: the second print() works in Python 3.5.3, but it does not in e.g. 3.7.2:
KeyError: 'bar'
is raised and I couldn't find a way to catch it.After some experiments, I found a difference in Python's behavior. In v3.5.3, the calls are
__getitem__(self, "foo")
which succeeds and__getitem__(self, "bar")
which can not find the key"bar"
, therefore it calls__missing__(self, "bar")
to handle the missing key without throwing a KeyError. In v3.7.2,__getattribute__(self, "keys")
is called internally. The built-inkeys()
method is used to return an iterator over the keys, which yields "foo",__getitem__("foo")
succeeds, then the iterator is exhausted. For{bar}
from the format string there is no key"bar"
.__getitem__()
and hence__missing_()
are not called to handle the situation. Instead, the KeyError is thrown. I don't know how one could catch it, if at all.In Python 3.2+ you should use
format_map()
instead (also see Python Bug Tracker - Issue 6081):If you want to keep the placeholders, you can do:
As you can see,
format_map()
does call__missing__()
.The following appears to be the most compatible solution as it also works in older Python versions including 2.x (I tested v2.7.15):
To keep placeholders as-is including the format spec (e.g.
{bar:<15}
) the Formatter needs to be subclassed:Note that the placeholder indices are not changed (
{1}
remains in the string without a{0}
), and in order to substitute{1}
you need to pass an array with any odd first element and what you want to substitute the remaining placeholder with as second element (e.g.[None, "actual"]
).You can also call the
format()
method with positional and named arguments:str.format()
不需要映射对象。试试这个:您使用返回“”的
str()
工厂创建一个 defaultdict。然后你为 defaultdict 创建一个键。在格式字符串中,您可以访问传递的第一个对象的键。这样做的优点是允许您传递其他键和值,只要您的 defaultdict 是format()
的第一个参数。另请参阅 http://bugs.python.org/issue6081
str.format()
doesn't expect a mapping object. Try this:You make a defaultdict with a
str()
factory that returns "". Then you make one key for the defaultdict. In the format string, you access keys of the first object passed. This has the advantage of allowing you to pass other keys and values, as long as your defaultdict is the first argument toformat()
.Also, see http://bugs.python.org/issue6081
不幸的是,不,默认情况下没有这样的方法。但是,您可以为其提供 defaultdict 或具有覆盖的 __getattr__ 的对象,并像这样使用:
Unfortunately, no, there is no such way to do by default. However you can provide it defaultdict or object with overridden
__getattr__
, and use like this:我制作了一个与 Daniel 的方法类似的版本,但没有 {0.x} 属性访问权限。
打印出来
I made a version that does work similarly to Daniel's method but without the {0.x} attribute access.
prints out