Python:float的子类可以在其构造函数中获取额外的参数吗?

Shi*_*ura 11 python types subclass built-in python-3.x

在Python 3.4中,我想创建一个子类float- 可以在数学和布尔操作中使用,例如a float,但具有其他自定义功能,并且可以在初始化时接收控制该功能的参数.(具体来说,我想要一个自定义__str__和该方法中使用的参数.)

但是,我似乎无法获得float具有功能性双参数构造函数的子类.为什么?这仅仅是扩展内置类型的限制吗?

例:

class Foo(float):
    def __init__(self, value, extra):
        super().__init__(value)
        self.extra = extra
Run Code Online (Sandbox Code Playgroud)

现在如果我尝试Foo(1,2)我得到:

TypeError: float() takes at most 1 argument (2 given)
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,我的新__init__论点也被强制执行,所以如果我这样做,Foo(1)我会得到:

TypeError: __init__() missing 1 required positional argument: 'extra'
Run Code Online (Sandbox Code Playgroud)

这是什么交易?我已经用子类型完成了类似的事情,list并且对它没有用处感到惊讶float.

cgo*_*lin 10

由于float是不可变的,你也必须覆盖__new__.以下应该做你想要的:

class Foo(float):
    def __new__(self, value, extra):
        return float.__new__(self, value)
    def __init__(self, value, extra):
        float.__init__(value)
        self.extra = extra

foo = Foo(1,2)
print(str(foo))
1.0
print(str(foo.extra))
2
Run Code Online (Sandbox Code Playgroud)

另请参见Python中的子类化浮点类型,无法在__init __()中捕获异常


kod*_*tin 5

@cgogolin和@qvpham均提供有效的答案。不过,我估计float.__init__(value)的范围内__init__的方法是无关的初始化Foo。也就是说,它不会初始化的属性Foo。这样,它反而导致在操作float类型子类化的必要性上造成混乱。

实际上,该解决方案可以进一步简化如下:

In [1]: class Foo(float):
   ...:     def __new__(cls, value, extra):
   ...:        return super().__new__(cls, value)
   ...:     def __init__(self, value, extra):
   ...:        self.extra = extra

In [2]: foo = Foo(1,2)
   ...: print(str(foo))
1.0

In [3]: print(foo.extra)
2
Run Code Online (Sandbox Code Playgroud)