在Python 2.5上,我需要使用经过修改的__str__()方法使用浮点数。我还需要知道构造函数何时失败。
__str__()
为什么我无法捕获来自的异常float.__init__()?
float.__init__()
查阅派生的float对象的数值的最佳方法是什么?在我的代码中,我使用float(self)。
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__根据该假设进行操作;-)。
float
__init__
self
因此,所有的行动发生在__new__中, 构造 适当的,就像其他不可变的类型,如int,str,tuple,等。一个普遍的错误是认为它__init__是一个构造函数:不是,它以一个已经构造的对象作为它的第一个参数self,然后“初始化”它(如果可行,即,如果self是可变的!-)- 构造 本身发生在__new__。
__new__
int
str
tuple
因此,您的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定义了异常类,它会更好;-)。
My_Error