小编典典

在Python中子类化float类型,无法在__init __()中捕获异常

python

在Python 2.5上,我需要使用经过修改的__str__()方法使用浮点数。我还需要知道构造函数何时失败。

为什么我无法捕获来自的异常float.__init__()

查阅派生的float对象的数值的最佳方法是什么?在我的代码中,我使用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

阅读 209

收藏
2021-01-16

共1个答案

小编典典

float是不可变的,因此它__init__初始化 程序基本上是一个空操作-
在那里什么都不会发生,因为self对象无法更改(如果它实际上float是子类的实例,而不是子类的实例),但是当然必须float自己__init__根据该假设进行操作;-)。

因此,所有的行动发生在__new__中, 构造
适当的,就像其他不可变的类型,如intstrtuple,等。一个普遍的错误是认为它__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

(当然,如果 确实My_Error定义了异常类,它会更好;-)。

2021-01-16