鱼C论坛

 找回密码
 立即注册
查看: 5787|回复: 9

[已解决]关于__add__与__sub__重载时报错Unexpected argument

[复制链接]
发表于 2020-11-3 21:15:36 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
各位带佬,今天学习到python的魔法方法那部分,小甲鱼写的
class New_int(int):
    def __add__(self, other):
        other = other
        return int.__sub__(self,other)
    def __sub__(self, other):
        return int.__add__(self,other)
是没有问题的,但是我把int改成super()之后,pycharm提示我   Unexpected argument   
现在一脸懵逼,super()按道理说,不是可以代替所有的父类吗,为什么会报错呢。
class New_int(int):
    def __add__(self, other):
        other = other
        return super().__sub__(self,other)
    def __sub__(self, other):
        return super().__add__(self,other)
各位带佬救命
最佳答案
2020-11-4 14:11:13
shirelee 发表于 2020-11-4 09:24
发现把int改成int()程序也是没有问题的,

用 super().__sub__ 和 int().__sub__ 是一样的,因为你的这个类的父类就是 int
这两种方法与 int.__sub__  的区别就是,后者是用类名调用方法,类名调用方法,就不需要self参数了;前者则不然,是调用的实例方法,需要self参数
可以看看我的这个帖子: python细节之8、类属性(方法)和类实例化属性(方法)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-11-3 22:25:15 | 显示全部楼层
改为super,那么后面的参数列表中则不再有self
int.__add__是用类名调用,需要两个参数,一个是运算符左值,一个是运算符右值
super().__add__则只需要一个参数,因为这样写是用对象调用,只需要一个右值
class New_int(int):
    def __add__(self, other):
        other = other
        return super().__sub__(other)
    def __sub__(self, other):
        return super().__add__(other)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-11-3 22:33:17 | 显示全部楼层
的确 super().__sub__() 这是调用了父类的__sub__方法,
但这就变成了是在“调用”(父类的某个方法),
而不是在定义(子类的某个方法),
所以,“正确地调用父类的方法”是:
serper().__sub__(other) 
# 去掉self,因为它代表子类对象本身(即实例化对象)
# 如果不去掉,父类的__sub__()执行时就多了个参数(即子类对象),
# 本来它在父类定义时,只需要一个参数。所以报错:Unexpected argument
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-4 08:51:08 | 显示全部楼层
阿奇_o 发表于 2020-11-3 22:33
的确 super().__sub__() 这是调用了父类的__sub__方法,
但这就变成了是在“调用”(父类的某个方法),
...

感觉大概明白了一些,那么如果是int的话,int.__sub__不也是调用父类的方法吗,为什么参数里面需要self呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-4 09:02:08 | 显示全部楼层
sunrise085 发表于 2020-11-3 22:25
改为super,那么后面的参数列表中则不再有self
int.__add__是用类名调用,需要两个参数,一个是运算符左值 ...

谢谢解答,所以这里super()其实是一个类对象? 在前面继承部分使用super()来继承父类的方法时,写在子类__init__方法中的super().__init__相当于也是调用了该类对象的__init__方法的意思吗? 那__new__的话为什么cls参数好像不能省略呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-4 09:24:11 | 显示全部楼层
sunrise085 发表于 2020-11-3 22:25
改为super,那么后面的参数列表中则不再有self
int.__add__是用类名调用,需要两个参数,一个是运算符左值 ...

发现把int改成int()程序也是没有问题的,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-11-4 10:48:26 | 显示全部楼层
本帖最后由 阿奇_o 于 2020-11-4 10:59 编辑
shirelee 发表于 2020-11-4 08:51
感觉大概明白了一些,那么如果是int的话,int.__sub__不也是调用父类的方法吗,为什么参数里面需要self呢


实际上,super().__sub__(参数1, 2, 3) 这是Python3才有的简略写法。
其实它也有self, 是 super(子类名, self).__sub__(参数1, 2, 3) 。
这里super(子类名, self) 可以理解为传入“子类名”(命名空间)和该子类的对象self,
然后拿着这两个去找爸爸(父类)。。因为它可以“多继承”--多个爸爸。。

int.__sub__()这种写法,是来自Python2的经典写法,即  父类名称.__init__(self, 参数1, 参数2, ...)

在理解上,你可以理解为是生成了一个父类对象而调用其方法,所以不用self。

在语法上,你只要记得,有这样三种写法,就好了。

1. super().__sub__(参数1, 2, 3 ) # 简化写法

2. super(子类名, self).__sub__(参数1, 2, 3 )

3. 父类名.__sub__(self, 参数1, 2, ...)

OK ^_
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-11-4 14:11:13 | 显示全部楼层    本楼为最佳答案   
shirelee 发表于 2020-11-4 09:24
发现把int改成int()程序也是没有问题的,

用 super().__sub__ 和 int().__sub__ 是一样的,因为你的这个类的父类就是 int
这两种方法与 int.__sub__  的区别就是,后者是用类名调用方法,类名调用方法,就不需要self参数了;前者则不然,是调用的实例方法,需要self参数
可以看看我的这个帖子: python细节之8、类属性(方法)和类实例化属性(方法)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-4 15:53:10 | 显示全部楼层
阿奇_o 发表于 2020-11-4 10:48
实际上,super().__sub__(参数1, 2, 3) 这是Python3才有的简略写法。
其实它也有self, 是 super(子类 ...

明白了 多谢多谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-4 15:54:33 | 显示全部楼层
sunrise085 发表于 2020-11-4 14:11
用 super().__sub__ 和 int().__sub__ 是一样的,因为你的这个类的父类就是 int
这两种方法与 int.__sub ...

明白了 谢谢您
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-18 00:24

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表