浮动子类以更改摄入量和__str__行为

问题描述 投票:3回答:4

我将float细分为更改其__str__()方法,使其以符号结尾(在我的情况下为€)。

[输入经过过滤以删除符号(在我的情况下为€)。

class Euro(float):
    def __new__(cls, value):
        v = ''.join([_ for  _ in value if _ != '€' ])
        return super(Euro, cls).__new__(cls, v)

    def __str__(self):
        return f'{self} €'

但是当我打印时,出现了递归打印错误。

g = Euro('123.23 €')
print (g) 

错误:

Euro.py, line  __str__
    return f'{self} €'

 [Previous line repeated 329 more times]

RecursionError: maximum recursion depth exceeded
python python-3.x subclass
4个回答
2
投票

使用super()调用父级的方法并避免递归错误。

def __str__(self):
    return super().__str__() + ' €'


>>> g = Euro('123.23 €')
>>> print(g)
123.23 €

1
投票

不要使用继承; Euro不是float的一种,并且由于实数浮点近似的不精确性,所以绝对不能使用float来表示货币。

相反,使用composition存储表示欧元数量的属性,并使用类似decimal.Decimal的表示欧元和美分exactly

from decimal import Decimal


class Euro:
    # In accordance with how to use super properly,
    # always accept and pass on unrecognized keyword arguments.
    def __init__(self, value, **kwargs):
        super().__init__(**kwargs)

        self.value = Decimal(value.strip('€'))

    def __str__(self):
        return f'{self.value} €'

0
投票

考虑代码,

def __str__(self):
    return f'{self} €'

[现在,当您调用print(g)时,实际发生的是print(g)调用了__str__Euro方法,该方法返回了f'{self} €',因为self引用了Euro本身的实例,这导致对__str__Euro方法的进一步调用,此递归一直持续到stackoverflow发生。

要解决此问题,您必须确保不应该进行递归,可以通过以下方式实现,

class Euro(float):
    def __new__(self, value):
        self.value =  "".join([_ for  _ in value if _ != '€' and _ != " " ])
        return float.__new__(self, self.value)

    def __str__(self):
        return f'{self.value} €' # or return super().__str__() + ' €'

现在调用时,print(g)这将返回,123.23 €如预期。

希望这会有所帮助!


0
投票

我结束了下面的代码:

from decimal import Decimal

class Euro:
    def __init__(self, value):
        if isinstance(value, str):
            value = value.strip(' €')
        self.value = Decimal(value)

    def __add__(self, other):
        return Euro(self.value + other.value)

    def __sub__(self,other):
        return Euro(self.value - other.value)

    def __str__(self):
        return f'{self.value} €'

我看不到需要分类的地方。我添加了对返回欧元对象的+/-运算符的支持。

结果是:

g = Euro(1.00)
h = Euro('10.00 €')

print (h+g) # --> 11.00 €
print (h-g) # -->  9.00 €
© www.soinside.com 2019 - 2024. All rights reserved.