为了账号安全,请及时绑定邮箱和手机立即绑定

__add__ 返回超类的实例而不是子类

__add__ 返回超类的实例而不是子类

牧羊人nacy 2022-10-18 16:02:11
当我对某个类进行子类int化并自定义它的__add__方法并调用super().__add__(other)它时,它会返回一个实例int,而不是我的子类。我可以通过在每个返回 an 的方法中的每次调用type(self)之前添加来解决这个问题,但这似乎过分了。必须有更好的方法来做到这一点。和s也会发生同样的事情。super()intfloatsfractions.Fractionclass A(int):    def __add__(self, other):        return super().__add__(other)x = A()print(type(x + 1))输出:<class 'int'>预期输出:<class '__main__.A'>
查看完整描述

3 回答

?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

这可以使用描述符来完成。以下类使用在类体内实例化该类时具有特殊效果的特殊方法。


class SuperCaller:


    def __set_name__(self, owner, name):

        """Called when the class is defined. owner is the class that's being

        defined. name is the name of the method that's being defined.

        """

        method = getattr(super(owner, owner), name)

        def call(self, other):

            # Note that this self shadows the __set_name__ self. They are two

            # different things.

            return type(self)(method(self, other))

        self._call = call


    def __get__(self, instance, owner):

        """instance is an instance of owner."""

        return lambda other: self._call(instance, other)



class A(int):

    __add__ = SuperCaller()



x = A()

print(type(x + 1))

输出:<class '__main__.A'>


查看完整回答
反对 回复 2022-10-18
?
偶然的你

TA贡献1841条经验 获得超3个赞

一种方法是创建一个装饰器,它可以用强制转换包装所需的数学运算:


def wrap_math(c):

    def wrapped(orig):

        return lambda s, o: c(orig(s,o))


    maths = ["__add__", "__sub__"]

    for op in maths:

        func = wrapped(getattr(c, op))

        setattr(c, op, func)


return c


@wrap_math

class Special(int)

    pass


 x = Special(10)

 type(x + 10)

完成您要包装的功能列表,您应该一切顺利。一种方法是创建一个装饰器,它可以用强制转换包装所需的数学运算:


def wrap_math(c):

    def wrapped(orig):

        return lambda s, o: c(orig(s,o))


    maths = ["__add__", "__sub__"]

    for op in maths:

        func = wrapped(getattr(c, op))

        setattr(c, op, func)


return c


@wrap_math

class Special(int)

    pass


 x = Special(10)

 type(x + 10)

完成您要包装的功能列表,您应该一切顺利。


查看完整回答
反对 回复 2022-10-18
?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

该super()函数从父类调用方法,int在这种情况下。相反,您应该在方法中初始化类__add__:


class A(int):

    def __add__(self, number):

        return A(self.numerator + number)


x = A(4)

print(type(x + 1))


查看完整回答
反对 回复 2022-10-18
  • 3 回答
  • 0 关注
  • 152 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号