代码之家  ›  专栏  ›  技术社区  ›  Robert Yi

为什么“new”返回的对象是可变的,即使对于不可变的基类也是如此?

  •  3
  • Robert Yi  · 技术社区  · 6 年前

    我定义了一个新的 float 子类如下:

    class newfloat(float):
        def __new__(cls, value, attribute):
            r = super().__new__(cls, value)
            r.attribute = attribute
            return r
    

    当我实例化一个 newfloat 对象,如下所示 新浮动 对象确实有一个属性 attribute . 例如。。。

    a = newfloat(1, 2)
    print(a.attribute)
    

    …这种回报 2 .

    因此,出于某种原因, r.attribute = attribute 工作,将第二个参数值赋给class属性 属性 . 但这对我来说没有意义,因为基本类型的对象, 浮动 ,是不变的!为什么会这样?

    1 回复  |  直到 6 年前
        1
  •  3
  •   wim    6 年前

    实际上,返回的对象 super().__new__(cls, value) 是一个 newfloat . 这就是为什么你通过 cls 当你打电话 super().__new__ .

    当定义一个新类时,默认情况下您将在实例上得到一个名称空间。( docs ,CTRL+F为“ 自定义类类型 “),除非您通过声明 __slots__ . 同样,您也可以为实例设置新的属性。

    >>> f = newfloat(1.23, 'ok')
    >>> f.__dict__
    {'attribute': 'ok'}
    >>> f.hello = 'world'
    >>> f.__dict__
    {'attribute': 'ok', 'hello': 'world'}
    >>> f
    1.23
    >>> hash(f) == hash(1.23)
    True
    

    作为开发人员,您的责任在于确保建模不可变类型的类的行为正确,就像不可变类型一样。