我想打印出像key+value一样的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))我想调试解析,看看是否可以获得格式字符串中插入的额外的“:”,但这会引发
KeyError:'‘在Python2.7和3.4中。如果我取消注释for循环以查看错误中发生了什么,但是最后的print语句将只显示一个换行符。
当我做最后一行时:
print('key {:<{}} {}'.format(k, w, v))这起作用(键后有空格),当我这样做时:
print('key {::<{}} {}'.format(k, w, v))我得到多个“:”而不是空格。但没有KeyError。
我为什么要拿到KeyError?我如何调试这个?
发布于 2015-09-08 12:46:01
这里有两个与此相关的问题,关于如何调试的简单答案是:您不能(至少不能使用print语句)或使用字符串格式的任何东西本身,因为这发生在另一种字符串格式中,并破坏格式化程序的状态。
它抛出错误是因为string.Formatter()不支持空字段,这是在C代码中的格式从2.6增加到3.1 (和2.7),但没有反映在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:后使用仅适用于非字符串类型(如+和-)的选项不同,则可能会得到不同的结果。
https://stackoverflow.com/questions/32457680
复制相似问题