Sub-classing float type in Python, fails to catch exception in __init__()

前端 未结 2 1308
忘了有多久
忘了有多久 2020-12-16 18:34

On Python 2.5 I need to use float numbers with a modified __str__() method. Also I need to know when the constructor fails.

Why I can\'t catch exception

相关标签:
2条回答
  • 2020-12-16 19:19

    float is immutable, therefore its __init__, the initializer, is basically a no-op -- nothing substantial can happen there, because the self object cannot be altered (if it's actually an instance of float rather than of a subclass -- but of course float's own __init__ must operate on that assumption;-).

    Therefore, all the action happens in __new__, the constructor proper, just like for other immutable types like int, str, tuple, and so on. It's a common mistake to believe that __init__ is a constructor: it's not, it takes an already-constructed object as its first argument, self, and "initializes" it (if feasible, i.e., if that self is mutable!-) -- the construction itself happens in __new__.

    So, your float subclass should start:

    class My_Number(float):
      def __new__(cls, float_string):
        try: return float.__new__(cls, float_string)
        except (TypeError, ValueError): raise My_Error(float_string)
    

    and you can remove the __init__, which is not needed. Now:

    >>> 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
    

    (of course, it would work even better if you did have a My_Error exception class defined;-).

    0 讨论(0)
  • 2020-12-16 19:24

    try __new__ instead:

    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")
    

    Also "self" is a float already so no need to say float(self), just "self" will do:

    def __str__(self):
        return "%.2f" % self
    
    0 讨论(0)
提交回复
热议问题