如何使用父__new__中的一些魔术来创建子类实例? [英] How to create child class instance using some magic in parent __new__?

查看:58
本文介绍了如何使用父__new__中的一些魔术来创建子类实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,在以下层次结构中创建自定义数字类型

For example, creating custom number types in following hierarchy


  • Number

    • 复杂

    • Real

      • Int

      • Float

      • Number
        • Complex
        • Real
          • Int
          • Float

          __ new __ 方法中具有逻辑:

          class Number:
              def __new__(cls, value):
                  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 Complex(Number):
              pass
          
          
          class Real(Number):
              def __new__(cls, value):
                  if isinstance(value, int):
                      return Int(value)
                  elif isinstance(value, float):
                      return Float(value)
                  else:
                      raise TypeError('Ты больше не можешь вести себя так!!!')
          
          
          class Int(Real):
              pass
          
          
          class Float(Real):
              pass
          

          然后,使用 Number 构造函数创建 Float 实例:

          And then, creating Float instance using Number constructor:

          number = Number(6.6)
          assert isinstance(number, Float)
          

          由于递归限制,此代码将引发 RuntimeError 。这只是期望行为的示例。但是我也尝试使用 super 来实现这一点,似乎我误解了世界。

          This code will raise RuntimeError because of recursion limit. It is just example of desired behaviour. But I also tried to implement this using super and it is seems I misunderstand the world.

          推荐答案

          您的复杂浮动 Int 类不是不是具有 __ new __ 方法,因此它们从 Number 继承这些方法;这就是导致您无限递归的原因。

          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.

          您可以针对 __ class __ 闭包进行测试,以查看是否具有是否子类:

          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
          

          并在 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('Ты больше не можешь вести себя так!!!')
          

          演示:

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

          这篇关于如何使用父__new__中的一些魔术来创建子类实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆