gpt4 book ai didi

python - string.Formatter 抛出 KeyError ''

转载 作者:太空宇宙 更新时间:2023-11-03 12:05:56 25 4
gpt4 key购买 nike

我想像 this question 那样打印键值对,

key a:         1
key ab: 2
key abc: 3
^ this colon is what I want

但我不喜欢那里的答案,我尝试像这样子类化 string.Formatter:

from __future__ import print_function

from string import Formatter

class KeyFormatter(Formatter):
def parse(self, fmtstr):
res = super(KeyFormatter, self).parse(fmtstr)
#for r in res:
# print(r)
return res

kf = KeyFormatter()
w = 10

x = dict(a=1, ab=2, abc=3)

for k in sorted(x):
v = x[k]
print(kf.format('key {::<{}} {}', k, w, v))

我想调试解析以查看是否可以获取格式字符串中插入的额外“:”,但这会抛出一个

按键错误:''在 Python 2.7 和 3.4 中。如果我取消注释 for 循环以查看发生了什么,错误就会消失,但最终的打印语句只会显示一个换行符。

当我写最后一行时:

print('key {:<{}} {}'.format(k, w, v))

这有效(键后有空格),当我这样做时:

print('key {::<{}} {}'.format(k, w, v))

我得到多个“:”而不是空格。但是没有 KeyError。

为什么我会得到 KeyError?我该如何调试?

最佳答案

这里有两个有点相关的问题,如何调试的简单答案是:你不能,至少不能使用 print 语句,或者任何本身使用字符串格式的东西,因为这会在另一种字符串格式期间发生并破坏状态格式化程序。

它抛出错误的原因是 string.Formatter() 不支持空字段,这是对格式从 2.6 到 3.1(和 2.7)的补充,它在 C 代码中,但未反射(reflect)在 string 模块中。

您可以通过继承 MyFormatter 类来模拟新行为:

from __future__ import print_function

from string import Formatter
import sys

w = 10
x = dict(a=1, ab=2, abc=3)

if sys.version_info < (3,):
int_type = (int, long)
else:
int_type = (int)

class MyFormatter(Formatter):

def vformat(self, *args):
self._automatic = None
return super(MyFormatter, self).vformat(*args)

def get_value(self, key, args, kwargs):
if key == '':
if self._automatic is None:
self._automatic = 0
elif self._automatic == -1:
raise ValueError("cannot switch from manual field specification "
"to automatic field numbering")
key = self._automatic
self._automatic += 1
elif isinstance(key, int_type):
if self._automatic is None:
self._automatic = -1
elif self._automatic != -1:
raise ValueError("cannot switch from automatic field numbering "
"to manual field specification")
return super(MyFormatter, self).get_value(key, args, kwargs)

那应该摆脱 KeyError。之后你应该覆盖方法 format_field 而不是 parse:

if sys.version_info < (3,):
string_type = basestring
else:
string_type = str

class TrailingFormatter(MyFormatter):
def format_field(self, value, spec):
if isinstance(value, string_type) and len(spec) > 1 and spec[0] == 't':
value += spec[1] # append the extra character
spec = spec[2:]
return super(TrailingFormatter, self).format_field(value, spec)

kf = TrailingFormatter()
w = 10

for k in sorted(x):
v = x[k]
print(kf.format('key {:t:<{}} {}', k, w, v))

并得到:

key a:         1
key ab: 2
key abc: 3

请注意在格式字符串中引入尾随字符的格式说明符 (t)。

Python 格式化例程实际上足够智能,可以让您在字符串中插入尾随字符,就像宽度格式化一样:

    print(kf.format('key {:t{}<{}} {}', k, ':', w, v))

给出相同的结果并允许您动态更改 ':'

您还可以将 format_field 更改为:

    def format_field(self, value, spec):
if len(spec) > 1 and spec[0] == 't':
value = str(value) + spec[1] # append the extra character
spec = spec[2:]
return super(TrailingFormatter, self).format_field(value, spec)

并提交任何类型:

print(kf.format('key {:t{}<{}} {}', (1, 2), '@', 10, 3))

得到:

key (1, 2)@    3

但是由于在将值传递给 Formatter.formatfield() 之前将值转换为字符串,如果 str(val) 为您提供与使用 {0}.format(val) 和/或 t: 之后的选项不同的值仅适用于非字符串类型(例如 +-)

关于python - string.Formatter 抛出 KeyError '',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32457680/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com