这与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"
答案 0 :(得分:1)
传递整数而不是字符串,它将正常工作。
>>> 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'
答案 1 :(得分:0)
它表示十是一个字符串,您试图将其格式化为数字。
尝试将其包装成演员:
>>> print '{0:d}, {0:02X}'.format(int(ten))
10, 0A
答案 2 :(得分:0)
解决此问题的第一种方法可能只是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
对象开发更复杂的方法。不过,我认为基于异常的方法为您提供了许多免费的内置功能。