Python中的子类化浮点类型无法捕获__init __()中的异常

时间:2009-12-20 17:51:35

标签: python exception-handling

在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

2 个答案:

答案 0 :(得分:18)

float是不可变的,因此它的__init__初始值设定项基本上是无操作的 - 那里不会发生任何实质性因素,因为self对象不能被改变(如果它实际上是float的实例而不是子类 - 但当然float自己的__init__必须根据该假设进行操作; - )。

因此,所有操作都在__new__构造函数正确,就像intstr,{{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