首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >子类string.Formatter

子类string.Formatter
EN

Stack Overflow用户
提问于 2014-02-09 20:05:31
回答 2查看 1.4K关注 0票数 5

下面是一个注释:如何定义新的字符串格式化程序,我尝试对string.Formatter进行子类化。这就是我所做的。不幸的是,我似乎在这个过程中打破了它。

代码语言:javascript
运行
复制
import string
from math import floor, log10

class CustFormatter(string.Formatter):
    "Defines special formatting"
    def __init__(self):
        super(CustFormatter, self).__init__()

    def powerise10(self, x):
        if x == 0: return 0, 0
        Neg = x < 0
        if Neg: x = -x
        a = 1.0 * x / 10**(floor(log10(x)))
        b = int(floor(log10(x)))
        if Neg: a = -a
        return a, b

    def eng(self, x):
        a, b = self.powerise10(x)
        if -3 < b < 3: return "%.4g" % x
        a = a * 10**(b%3)
        b = b - b%3
        return "%.4g*10^%s" % (a, b)

    def format_field(self, value, format_string):
      # handle an invalid format
      if format_string == "i":
          return self.eng(value)
      else:
          return super(CustFormatter,self).format_field(value, format_string)

fmt = CustFormatter()
print('{}'.format(0.055412))
print(fmt.format("{0:i} ", 55654654231654))
print(fmt.format("{} ", 0.00254641))

好像在最后一行中,我没有按位置引用变量,而是得到了一个KeyError。这显然是期待一个键,这是可选的,在原来的课程,但我不明白为什么,我不知道我做错了什么。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-02-09 20:30:25

str.format 自动编号string.Formatter没有。

修改__init__和重写get_value就可以做到这一点。

代码语言:javascript
运行
复制
def __init__(self):
    super(CustFormatter, self).__init__()
    self.last_number = 0

def get_value(self, key, args, kwargs):
    if key == '':
        key = self.last_number
        self.last_number += 1
    return super(CustFormatter, self).get_value(key, args, kwargs)

顺便说一句,上面的代码并不严格模仿str.format行为。如果我们将自动编号和手动编号混为一谈,str.format会抱怨,但上面没有。

代码语言:javascript
运行
复制
>>> '{} {1}'.format(1, 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: cannot switch from automatic field numbering to manual field specification
>>> '{0} {}'.format(1, 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: cannot switch from manual field specification to automatic field numbering
票数 5
EN

Stack Overflow用户

发布于 2014-02-09 20:36:15

好消息:你没有做错什么。坏消息:这就是string.Formatter的行为方式,它不支持{}-like位置格式。因此,即使没有子类,最后一次调用也会失败。好消息:可以通过重写parse方法来解决这个问题:

代码语言:javascript
运行
复制
import string

class CF(string.Formatter):
    def parse(self, s):
        position = 0
        for lit, name, spec, conv in super(CF, self).parse(s):
            if not name:
                name = str(position)
                position += 1
            yield lit, name, spec, conv

坏消息..。啊,不,基本上就是这样:

代码语言:javascript
运行
复制
>>> CF().format('{} {}!', 'Hello', 'world')
'Hello world!'
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21664318

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档