【发布时间】:2020-04-01 06:56:44
【问题描述】:
我正在尝试创建一个类MyFloat,它与float 非常相似,但有一个value 方法和一些其他方法。我还需要这个类的实例来与真正的floats 进行交互,并且在type(MyFloat(5) + 4) 是MyFloat 而不是float 的意义上是“粘性的”。
这就是我目前所拥有的:
class MyFloat(numbers.Real):
def __init__(self, value):
self._value = float(value)
@property
def value(self):
return self._value
@value.setter
def value(self, value):
self._value = float(value)
def __float__(self):
return self.value
但现在我必须实现大量其他方法才能满足抽象基类numbers.Real 以及我的要求,即它像float 一样“行动”。问题是a)有很多这些方法(__add__、__trunc__、__floor__、__round__、__floordiv__...我认为总共有 24 个)和 b)它们都遵循相同的图案。也就是说,对于任何方法,我可能只想:
def __method__(self):
return MyFloat(float.__method__(float(self))
或
def __method__(self, other):
return MyFloat(float.__method__(float(self), float(other)))
有没有办法在不手动实现每个数学方法(并重复大量代码)的情况下做我想做的事?
请记住,float.__method__ 实际上并不适用于每种方法。比如float.__floor__不存在,但我还是需要实现MyFloat.__floor__来满足numbers.Real抽象基类。
编辑:建议是扩展float,这也是我的第一个想法,但我失去了“粘性”要求。例如:
>>> class MyFloat(float):
def other_method(self):
print("other method output")
>>> mf = MyFloat(8)
>>> mf.other_method()
other method output
>>> o = mf + 9
>>> type(o)
<class 'float'>
>>> o.other_method()
Traceback (most recent call last):
File "<input>", line 1, in <module>
AttributeError: 'float' object has no attribute 'other_method'
【问题讨论】:
-
您是否在问是否有一种方法可以创建现有对象类型的副本,而无需手动实现所有方法?
-
您可以在循环中使用
__getattr__或exec和字符串格式来做一些诡计。 -
@user1558604 不,我知道我可以从 float 继承,但我失去了我的“价值”方法和我的“粘性”要求。 (afaik)@MichaelButscher 我没碰
exec;-) -
如果你想继承浮点数,为什么不实际这样做:
class MyFloat(float):,然后在初始化函数super().__init__(value)。这样浮动类的所有属性和方法也在你的类中 -
如果你扩展float,你应该能够使用它的所有功能并在上面添加你自己的。