在Python 2.5上,我需要使用带有修改后的__str__()
方法的浮点数。此外,我需要知道构造函数何时失败。
为什么我无法捕捉float.__init__()
提出的异常?
查询派生浮点对象的数值的最佳方法是什么?在我的代码中,我正在使用float(self)
。
class My_Number(float):
def __init__(self, float_string):
try:
super(My_Number, self).__init__(float_string)
except (TypeError, ValueError):
raise My_Error(float_string)
def __str__(self):
if int(float(self)) == float(self):
return str(int(float(self)))
else:
return str(round(float(self), 2))
>>> n = My_Number('0.54353')
>>> print n
0.54
>>> n = My_Number('5.0')
>>> print n
5
>>> n = My_Number('foo')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for float(): foo
答案 0 :(得分:18)
float
是不可变的,因此它的__init__
,初始值设定项基本上是无操作的 - 那里不会发生任何实质性因素,因为self
对象不能被改变(如果它实际上是float
的实例而不是子类 - 但当然float
自己的__init__
必须根据该假设进行操作; - )。
因此,所有操作都在__new__
,构造函数正确,就像int
,str
,{{1}等其他不可变类型一样}, 等等。认为tuple
是一个构造函数是一个常见的错误:它不是,它需要一个已经构造的对象作为它的第一个参数__init__
,并“初始化”它(如果可行的话,即,如果是self
是可变的! - ) - 构建本身发生在self
。
因此,您的__new__
子类应该开始:
float
您可以删除不需要的class My_Number(float):
def __new__(cls, float_string):
try: return float.__new__(cls, float_string)
except (TypeError, ValueError): raise My_Error(float_string)
。现在:
__init__
(当然,如果确实定义了>>> n = My_Number('foo')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in __new__
NameError: global name 'My_Error' is not defined
异常类,它会更好用.--)。
答案 1 :(得分:7)
尝试__new__
代替:
class F(float):
def __new__(cls, *arg, **kw):
try:
return float.__new__(cls, *arg, **kw)
except ValueError:
raise Exception("foo")
print F("3.5")
print F("asdf")
“自我”也是一个浮动,所以不需要说浮动(自我),只需“自我”就可以了:
def __str__(self):
return "%.2f" % self