Python:float的子类可以在其构造函数中获取额外的参数吗?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python:float的子类可以在其构造函数中获取额外的参数吗?相关的知识,希望对你有一定的参考价值。
在Python 3.4中,我想创建一个float
的子类 - 可以在数学和布尔运算中使用,如float
,但具有其他自定义功能,并且可以在初始化时接收控制该功能的参数。 (具体来说,我想要一个自定义的__str__
和该方法中使用的参数。)
但是,我似乎无法获得float
的子类来拥有一个功能性的双参数构造函数。为什么?这仅仅是扩展内置类型的限制吗?
例:
class Foo(float):
def __init__(self, value, extra):
super().__init__(value)
self.extra = extra
现在,如果我尝试Foo(1,2)
我得到:
TypeError: float() takes at most 1 argument (2 given)
令人惊讶的是,我的新__init__
的论点也被强制执行,所以如果我做Foo(1)
我得到:
TypeError: __init__() missing 1 required positional argument: 'extra'
这是什么交易?我用list
的子类型做了类似的事情,并且惊讶它在float
上没有用。
由于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
另见Sub-classing float type in Python, fails to catch exception in __init__()
@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
cgogolin的解决方案是正确的。它就像使用另一个不可变的类,如int,str,...但我会写:
class Foo(float):
def __new__(cls, value, extra):
return super().__new__(cls, value)
def __init__(self, value, extra):
float.__init__(value)
self.extra = extra
您可以在不实施__init__
的情况下执行此操作:
class Foo(float):
def __new__(cls, value, extra):
instance = super().__new__(cls, value)
instance.extra = extra
return instance
正在使用:
>>> foo = Foo(1, 2)
>>> print(foo)
1.0
>>> print(foo.extra)
2
以上是关于Python:float的子类可以在其构造函数中获取额外的参数吗?的主要内容,如果未能解决你的问题,请参考以下文章
Python 3:当子构造函数的参数多于父构造函数时,从继承的方法返回新的子类实例