【问题标题】:Instantiate Decimal class实例化十进制类
【发布时间】:2012-11-02 11:31:01
【问题描述】:

我在十进制模块中发现了一个奇怪的行为。 Decimal 类的“签名”是:

Decimal(value='0', context=None)

所以,我想我可以这样做:Decimal('3', None)。但是这段代码在 python3.3 中引发了 TypeError 异常,但在 python2.7 中没有。

在我的调查中,我尝试使用 pdb:pdb.set_trace("Decimal('3', None)") 进行调试,但没有任何反应!只要我输入s,就会引发同样的异常。

谁能解释这些行为的原因?

【问题讨论】:

  • 对于它的价值,我无法在 Python 3.2.3 下重现这个:import decimal; decimal.Decimal("3", None) 成功返回 Decimal('3')
  • @SilentGhost:我在链接中看到这是模块的 c 加速器版本中的错误(无论这是什么)。这可以解释为什么我从 pdb 中一无所获。但是我可以指定我想要纯 python 版本吗?
  • @GTux:这将是一个黑客。你不能只检查你传递给构造函数的内容吗?
  • @SilentGhost:这就是我正在做的。我想学习一个新技巧:)

标签: python-3.3


【解决方案1】:

我可以确认 Python 3.3 的行为。它以某种方式检测到您将 None 作为上下文传递并且它不喜欢它(即使它被记录为默认值)。

Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:57:17) [MSC v.1600 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import decimal
>>> decimal.Decimal('3', None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: optional argument must be a context
>>> decimal.Decimal('3')
Decimal('3')

更新:但它适用于 3.2.3

Python 3.2.3 (default, Apr 11 2012, 07:12:16) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import decimal
>>> decimal.Decimal('3', None)
Decimal('3')
>>>

更新:原因可以在文档中找到...

What’s New In Python 3.3 说:

十进制

issue 7652 - 集成快速原生十进制算术。 Stefan Krah 编写的 C 模块和 libmpdec。

比较decimal.py文件时,乍一看它们可能看起来一样,但Python 3.3版本的最后几乎包含以下代码:

try:
    import _decimal
except ImportError:
    pass
else:
    s1 = set(dir())
    s2 = set(dir(_decimal))
    for name in s1 - s2:
        del globals()[name]
    del s1, s2, name
    from _decimal import *

... 而旧的 Python 3.2 没有。它表示如果可以导入二进制 _decimal 实现,则来自 decimal.py 的旧实现将被忽略。并且二进制模块无法使用 Python 代码调试器进行调试。

问题是观察到的行为是否不应被视为错误。

【讨论】:

  • 就像我说的,我只是想了解这种行为,以及为什么我看不到 pdb 的代码执行。在我的代码中,我使用了一个丑陋的解决方法(我测试 context 并调用适当的表单)。
  • 谢谢,现在我明白了。关于您的问题,显然该错误已打开,请参阅 SilentGhost 评论。
  • @GTux:Silent Ghost 提到的黑客可能是注释掉答案中提到的try 块。但在这种情况下,我建议将其重命名并将其放入您的脚本目录——比如mydecimal.py
  • 现在我知道为什么会这样了,我可以安然入睡,继续使用我的旧 hack(在实例化之前测试 context),然后等待错误修复。
  • @GTux:是的。并且不要忘记添加评论您为什么这样做。 (你知道,Zaphod Beeblebrox 忘了这样做...... :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-27
  • 1970-01-01
  • 1970-01-01
  • 2013-08-22
相关资源
最近更新 更多