我将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
使用super()
调用父级的方法并避免递归错误。
def __str__(self):
return super().__str__() + ' €'
>>> g = Euro('123.23 €')
>>> print(g)
123.23 €
不要使用继承; 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} €'
考虑代码,
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 €
如预期。
希望这会有所帮助!
我结束了下面的代码:
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 €