我和这个人有同样的问题,可能还有这个人,但我是来分享一些代码并回答问题的!
我在批处理作业中有一些代码,它通过 pyodbc 从 Microsoft Access 数据库中读取字段并准备输出以供显示。
这是一个片段。注意断言。
def format_currency(amount):
if amount is None:
return ""
else:
result = "$%.2f" % amount
assert ":" not in result, (
"That's weird. The value %r of class %s is represented as %s" %
(amount, amount.__class__, result))
return result
当我运行它时,它成功处理了 100,000 行,然后失败了:
AssertionError: That's weird. The value Decimal('54871.0000') of class <class
'decimal.Decimal'> is represented as $54870.:0
注意异常的冒号。它很少发生 - 大约在 300,000 条记录中出现一次。
当我尝试隔离它时,它当然有效。
from decimal import Decimal
print "$%.2f" % Decimal('54871.0000')
$54871.00
Access中的字段类型为:
- 数据类型:货币
- 小数位数:2
- 输入掩码:
- 默认值:
- 验证规则:
- 文本对齐:常规
基于证据不足,我模糊的指责怀疑:pyodbc 正在探索 Decimal 的内部,可能被 Access 损坏弄糊涂了。正如@ecatmur指出的那样:
':' 在 ASCII 中是 '9' + 1
有人看到这个并解决了吗?
版本:
- Python 2.7.4
- pyodbc 3.0.6(最新)
- 访问 2010
- Windows 7的
进一步挖掘:
该decimal
模块是在 Python 中实现的。根据我的阅读,这些值由四个属性描述:_exp
, _int
, _sign
,_is_special
怀疑有损坏,我打印出这些字段的值。
令人惊讶的是,对于故障版本和工作版本,我得到:
_exp: -4
_int: 548710000
_sign: 0
_is_special: False
这很奇怪。
在decimal
模块中,__float__
函数的定义相当简单:
def __float__(self):
"""Float representation."""
return float(str(self))
但是当我用坏数据做这个时:
print "Str", str(amount)
print "Float", float(amount)
我得到:
力量 54871.0000
浮动 54870.:
我学得越多,它就越不奇怪。