На 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
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
; -).
попробуйте __ 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