Разделение на подклассы типа плавающего в Python, сбои для ловли исключения в __ init __ ()

На 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
10
задан Ricardo 20 December 2009 в 17:51
поделиться

2 ответа

float является неизменным, поэтому его __ init __ , инициализатор , по сути, не работает - там ничего существенного не может произойти, потому что объект self не может быть изменен (если он на самом деле является экземпляром float , а не подклассом - но, конечно, float собственный ] __init __ должен оперировать этим предположением; -).

Следовательно, все действие происходит в __ new __ , собственно конструкторе , как и для других неизменяемых типов, таких как ] int , str , 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

(конечно, было бы еще лучше, если бы у вас был определен класс исключения My_Error ; -).

19
ответ дан 3 December 2019 в 16:10
поделиться

попробуйте __ 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")

Также «self» уже является плавающим, поэтому нет необходимости говорить float (self), достаточно будет «self»: ​​

def __str__(self):
    return "%.2f" % self
7
ответ дан 3 December 2019 в 16:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: