假设我想创建一个现有类的自己的版本。让我们选择内置的float类。在本例中,我将创建一个类似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类继承,当我执行任何其他操作(即方法)时,结果将是一个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 zeroa方法与继承自父float类的方法一样,显然会返回一个浮点数。
所以我的问题是:有没有一种巧妙的方法可以让子类中所有继承的方法返回一个在子类中的结果,而不需要重写所有的方法?我在想一些类似装饰器@myfloat的东西,它会自动应用于所有(适用的)继承方法,将它们的结果从float类型转换为myfloat类型。
发布于 2018-02-28 21:35:12
这里有一种使用装饰器的方法,它可以将工作减少到每个需要类型转换的方法一行。它甚至集成了@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我真的不知道有没有办法解决这个问题。
https://stackoverflow.com/questions/49027131
复制相似问题