How to create child class instance using some magic in parent __new__?

前端 未结 1 1669
既然无缘
既然无缘 2020-12-22 07:45

For example, creating custom number types in following hierarchy

  • Number
    • Complex
    • Real
      • In
相关标签:
1条回答
  • 2020-12-22 08:18

    Your Complex, Float and Int classes do not have __new__ methods, so they inherit these from Number; this is what is causing your infinite recursion.

    You could test against the __class__ closure to see if you have a subclass or not:

    class Number:
        def __new__(cls, value):
            if cls is not __class__:
                # Subclass, create an instance (invokes object.__new__)
                return super().__new__(cls)
    
            if isinstance(value, complex):
                return Complex(value)
            elif isinstance(value, (int, float)):
                return Real(value)
            else:
                raise TypeError('Ну ты и мудак!!!')
    
        def __init__(self, value):
            self.value = value
    

    and do the same in Real:

    class Real(Number):
        def __new__(cls, value):
            if cls is not __class__:
                # Subclass, create an instance
                return super().__new__(cls, value)
    
            if isinstance(value, int):
                return Int(value)
            elif isinstance(value, float):
                return Float(value)
            else:
                raise TypeError('Ты больше не можешь вести себя так!!!')
    

    Demo:

    >>> class Number:
    ...     def __new__(cls, value):
    ...         if cls is not __class__:
    ...             # Subclass, create an instance
    ...             return super().__new__(cls)
    ...         if isinstance(value, complex):
    ...             return Complex(value)
    ...         elif isinstance(value, (int, float)):
    ...             return Real(value)
    ...         else:
    ...             raise TypeError('Ну ты и мудак!!!')
    ...     def __init__(self, value):
    ...         self.value = value
    ... 
    >>> class Real(Number):
    ...     def __new__(cls, value):
    ...         if cls is not __class__:
    ...             # Subclass, create an instance
    ...             return super().__new__(cls, value)
    ...         if isinstance(value, int):
    ...             return Int(value)
    ...         elif isinstance(value, float):
    ...             return Float(value)
    ...         else:
    ...             raise TypeError('Ты больше не можешь вести себя так!!!')
    ... 
    >>> class Complex(Number):
    ...     pass
    ... 
    >>> class Int(Real):
    ...     pass
    ... 
    >>> class Float(Real):
    ...     pass
    ... 
    >>> number = Number(6.6)
    >>> isinstance(number, Float)
    True
    
    0 讨论(0)
提交回复
热议问题