【问题标题】:String formatting with “{0:d}” doesn't convert to integer带有“{0:d}”的字符串格式不会转换为整数
【发布时间】:2012-07-13 04:05:30
【问题描述】:

这与this question about floats 中的问题大致相同。

当您有一个可以转换为整数的值时,旧的%d 会转换它,但格式不会。

class MyIntegerTenClass:
    def __int__(self):
        return 10
    def __str__(self):
        return 'ten'
ten = MyIntegerTenClass()
print '%d, %02X, %s' % (ten, ten, ten) # ok
print  '{0}'.format(ten) # ok
print  '{0:d}, {0:02X}'.format(ten) # ValueError: Unknown format code 'd' for object of type 'str'

有没有办法修改格式的行为,而不触及要格式化的值的类(不向该类添加__format__ 方法)?

编辑:我的目标是使格式取决于格式字符串,而不是值。 因此,如果格式字符串显示“d”或“x”,则将值转换为 int,然后转换为十进制或十六进制表示。 如果格式字符串为“s”,则直接将其转换为字符串。就像旧的 % 所做的那样。

实际上,我什至可以将__format__ 方法添加到值的类中。但是,如果给定的格式规范是整数格式规范,我该如何检查呢?无需重新实现内置格式的格式规范解析器。

编辑:这是__format__ 和异常的解决方案。有更好的想法吗?

class MyIntegerTenClass:
    def __int__(self):
        return 10
    def __str__(self):
        return 'ten'
    def __format__(self, spec):
        fmt = '{0:%s}'%spec
        try:
            return fmt.format(str(self))
        except:
            return fmt.format(int(self))
ten = MyIntegerTenClass()
print '%d, %02X, %s' % (ten, ten, ten) # ok, prints "10, 0A, ten"
print  '{0:d}, {0:02X}, {0}'.format(ten) # ok, prints "10, 0A, ten"

【问题讨论】:

  • 它说十是一个字符串,你正试图将它格式化为一个数字。
  • 我只是在格式规范中使用!s,在应用字段参数之前强制转换为字符串:'{0:d}, {0:02X}, {0!s}'.format(ten)。另外,使用return format(int(self), spec) 不需要在这里新建字符串模板,有完美的format() 函数。

标签: python string-formatting


【解决方案1】:

解决这个问题的第一种方法可能是简单地try它:

class MyIntegerTenClass:
    def __int__(self):
        return 10
    def __str__(self):
        return 'ten'
    def __format__(self, format_spec):
        try:
            s = format(str(self), format_spec)
        except ValueError:
            s = format(int(self), format_spec)
        return s

如果MyIntegerTenClass可以作为字符串插入到格式字符串中,就可以了。如果不是,则将其转换为 int 并重新提交给format

>>> print '{0}, {0:s}, {0:d}, {0:02X}, {0:f}'.format(ten)
ten, ten, 10, 0A, 10.000000

如果您希望默认表示为 10 而不是 ten,则只需交换转换行:

    def __format__(self, format_spec):
        try:
            s = format(int(self), format_spec)
        except ValueError:
            s = format(str(self), format_spec)
        return s

测试输出:

>>> print '{0}, {0:s}, {0:d}, {0:02X}, {0:f}'.format(ten)
10, ten, 10, 0A, 10.000000

作为附录,我不相信如果不定义__format__,您将能够获得您想要的行为;但是,您可以使用Formatter 对象开发更复杂的方法。尽管如此,我认为基于异常的方法为您提供了许多免费的内置功能。

【讨论】:

  • 谢谢。似乎我们几乎在同一时间得到了相同的解决方案(请参阅我的第二次编辑)。尽管您的解决方案似乎更好一些,因为它不需要 '{0:%s}'%spec。我没有意识到您可以像这样调用格式函数。
【解决方案2】:

传递一个整数而不是字符串,它会正常工作。

>>> print  '{0:d}'.format(1)
1
>>> print  '{0:d}'.format('1')

Traceback (most recent call last):
  File "<pyshell#57>", line 1, in <module>
    print  '{0:d}'.format('1')
ValueError: Unknown format code 'd' for object of type 'str'

【讨论】:

  • 我知道。但我不想传递一个整数。我想传递一个可以转换为整数的类的对象。
【解决方案3】:

它说十是一个字符串,你正试图将它格式化为一个数字。

尝试将其包装在演员表中:

>>> print  '{0:d}, {0:02X}'.format(int(ten))
10, 0A

【讨论】:

  • 不适用于我的用例。我不想更改给定格式的值。
猜你喜欢
  • 2021-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-07
  • 2017-02-22
  • 1970-01-01
相关资源
最近更新 更多