首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >类继承-所有继承的方法都可以强制转换为子类类型吗?

类继承-所有继承的方法都可以强制转换为子类类型吗?
EN

Stack Overflow用户
提问于 2018-02-28 18:20:42
回答 1查看 55关注 0票数 1

假设我想创建一个现有类的自己的版本。让我们选择内置的float类。在本例中,我将创建一个类似float的类,该类在除以零时不会引发错误,而是返回字符串'inf‘(请记住,这只是一个示例。避免被零除错误不是这个问题的重点)。

代码语言:javascript
运行
复制
class myfloat(float):
    def __truediv__(self, b):
        if b == 0:
            return 'inf'
        else:
            return myfloat(self.__float__() / b)

当除法与int或float结合使用时,它也可以工作。

代码语言:javascript
运行
复制
In[88]: a = myfloat(10)
In[89]: a / 2
Out[89]: 5.0
In[90]: a / 0
Out[90]: 'inf'

然而,由于从float类继承,当我执行任何其他操作(即方法)时,结果将是一个float。例如:

代码语言:javascript
运行
复制
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

a方法与继承自父float类的方法一样,显然会返回一个浮点数。

所以我的问题是:有没有一种巧妙的方法可以让子类中所有继承的方法返回一个在子类中的结果,而不需要重写所有的方法?我在想一些类似装饰器@myfloat的东西,它会自动应用于所有(适用的)继承方法,将它们的结果从float类型转换为myfloat类型。

EN

回答 1

Stack Overflow用户

发布于 2018-02-28 21:35:12

这里有一种使用装饰器的方法,它可以将工作减少到每个需要类型转换的方法一行。它甚至集成了@Graipher的self.__class__提示,这使得装饰器在没有任何变化的情况下工作,以防你有一天重命名myfloat

代码语言:javascript
运行
复制
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

然后你就会得到..。

代码语言:javascript
运行
复制
In [1]: (myfloat(3.3) +  4) / 0
Out[1]: 'inf'

人们甚至可以更进一步,列出这些函数的列表,在循环中将它们全部转换为类型,但我不认为它们有那么多。

但是:

如果另一个类型处理该操作,它仍然不起作用,就像下面这样:

代码语言:javascript
运行
复制
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

我真的不知道有没有办法解决这个问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49027131

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档