将浮点数转换为十进制数,保留 str() 表示法

3

我正在尝试对decimal.Decimal进行子类化,以便将浮点数视为字符串,然后将其视为小数。

与其这样做:

>>> decimal.Decimal(1.1)
Decimal('1.100000000000000088817841970012523233890533447265625')

我将浮点数转换为字符串,然后再将其转换为Decimal类型:
>>> decimal.Decimal(str(1.1))
Decimal('1.1')

因为我经常需要这样做,所以我决定对Decimal进行子类化。但是以下代码在Python 3.6.4中引发了异常:

import decimal

class D(decimal.Decimal):
    def __new__(self, value="0", context=None):
        value = str(value)
        super().__new__(value, context)

d = D(1.1)
print(d)

追踪:

Traceback (most recent call last):
  File "C:/Users/Better/.PyCharmCE2018.1/config/scratches/scratch_4.py", line 8, in <module>
    d = D(1.1)
  File "C:/Users/Better/.PyCharmCE2018.1/config/scratches/scratch_4.py", line 6, in __new__
    super().__new__(value, context)
TypeError: decimal.Decimal.__new__(X): X is not a type object (str)

解决方案是什么?

2个回答

3

尝试:

super().__new__(self, value, context)

def __new__(self, value="0", context=None):需要三个位置参数:selfvaluecontext

当你执行super().__new__(value, context)时,self(来自你的函数)变成了valuecontext也变成了value。最后两个值不需要被定义就可以使用该函数,因此没有任何提示告诉你这一点,context实际上从未传递给super().__new__()


1
我尝试用 super().__new__(self, value, context) 替换了这一行。结果:没有错误,但输出为 None - ChaimG
@ChaimG 然后按照上述建议 return super().__new__(value, context) 返回值。 - Xantium

3
您正在向__new__传递错误的参数,并且没有返回任何内容。

有关如何使用__new__的文档

class D(decimal.Decimal):

    def __new__(cls, value="0", context=None):
        value = str(value)
        return super().__new__(cls, value, context)

话虽如此,您在这里可能应该使用__init__,因为您没有进行任何需要使用__new__的类类型操作。

class D(decimal.Decimal):

    def __init__(self, value="0", context=None):
        value = str(value)
        super().__init__(self, value, context)

3
我们不能在这里使用__init__,因为Decimal类不使用__init__。在源代码中指出:“我们是不可变的,所以使用__new__而不是__init__”。此外,__init__不应该返回任何内容。 - ducminh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接