类继承 - 是否可以将所有继承的方法转换为子类类型?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了类继承 - 是否可以将所有继承的方法转换为子类类型?相关的知识,希望对你有一定的参考价值。
假设我想创建自己的现有类版本。我们选择内置的float类。在这个例子中,我将创建一个像类一样的浮点数,当除以零时不会引发错误,而是返回字符串'inf'(请记住这只是一个例子。避免除零错误不是这个的主要观点题)。
class myfloat(float):
def __truediv__(self, b):
if b == 0:
return 'inf'
else:
return myfloat(self.__float__() / b)
当除法与int或float耦合时,它也可以工作。
In[88]: a = myfloat(10)
In[89]: a / 2
Out[89]: 5.0
In[90]: a / 0
Out[90]: 'inf'
但是,由于float类的继承,当我进行任何其他操作(即方法)时,结果将是一个浮点数。例如:
In[92]: b = myfloat(20)
In[93]: (a + b) / 0
ZeroDivisionError Traceback (most recent call last)
<ipython-input-6-f769cd843514> in <module>()
----> 1 (a + b) / 0
ZeroDivisionError: float division by zero
添加方法仍然不会改变从父浮点类继承的方法,显然会返回一个浮点数。
所以我的问题是:有没有一种巧妙的方法让子类中的所有继承方法返回子类中的结果,而不需要重写所有方法?我想像装饰器@myfloat
被自动应用于所有(适用的)继承方法,将其结果从类型float
转换为类型myfloat
。
答案
这是一种装饰器的方法,它可以减少每个需要进行类型转换的方法的单行数。它甚至包含了@Graipher的self.__class__
提示,这使得装饰工作没有变化,以防你有一天重命名myfloat
。
def cast_return(func):
""" Decorator that casts the return value of a special __method__
back to the original type of 'self'. """
def wrapped(self, *args, **kwargs):
return self.__class__(func(self, *args, **kwargs))
return wrapped
class myfloat(float):
def __truediv__(self, b):
if b == 0:
return 'inf'
else:
return myfloat(self.__float__() / b)
__mul__ = cast_return(float.__mul__)
__add__ = cast_return(float.__add__)
# repeat for all the needed operations
然后你得到......
In [1]: (myfloat(3.3) + 4) / 0
Out[1]: 'inf'
人们甚至可以更进一步,列出这些函数,将它们全部集中在一个循环中,但我不认为它们是那么多。
但:
如果另一个类型处理操作,它仍然无法工作,如下所示:
In [1]:(4 + myfloat(3.3)) / 0
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-45-6537eb18ab79> in <module>()
16 __add__ = cast_return(float.__add__)
17
---> 18 (4 + myfloat(3.3)) / 0
ZeroDivisionError: float division by zero
我真的不知道是否有办法解决这个问题。
以上是关于类继承 - 是否可以将所有继承的方法转换为子类类型?的主要内容,如果未能解决你的问题,请参考以下文章
java中,子类能调用父类中所有方法、对象吗?是不是父类也能调用子类所有……?