python运算符重载之字符串显示和右侧加法

1 python运算符重载之字符串显示和右侧加法

1.1 重载字符串显示

1.1.1 str和repr

python调用prin()t时,自动调用__str__和__repr__,

python调用str()时,自动调用__str__和__repr__,

python调用repr()时,自动调用__repr__,不调用 str

终端用__str__,开发时用__repr__。

自定义__str__和__repr__时,必须返回字符串。

python 复制代码
>>> class MyAdd:
    def __init__(self,value=0):
        self.data=value
    def __add__(self,other):
        self.data+=other
>>> class MyAddRepr(MyAdd):
    def __repr__(self):
        return 'MyAddRepr({})'.format(self.data)
>>> ma=MyAdd(1)
>>> print(ma)
<__main__.MyAdd object at 0x03869C90> 
>>> mar=MyAddRepr(1)
# print 自动调用 __repr__
>>> print(mar)
MyAddRepr(1)
# str repr 自动调用 __repr__
>>> str(mar),repr(mar)
('MyAddRepr(1)', 'MyAddRepr(1)')

>>> class MyAddStr(MyAdd):
    def __str__(self):
        return 'MyAddStr({})'.format(self.data)
>>> mas=MyAddStr(2)
# print 自动调用 __str__
>>> print(mas)
MyAddStr(2)
# str 自动调用 __str__
# repr 不会调用 __str__
>>> str(mas),repr(mas)
('MyAddStr(2)', '<__main__.MyAddStr object at 0x03869CD0>')

>>> class MyAddBoth(MyAdd):
    def __str__(self):
        return 'MyAddBothstr({})'.format(self.data)
    def __repr__(self):
        return 'MyAddBothrepr({})'.format(self.data)

    
>>> mab=MyAddBoth(3)
# print str 自动调用 __str__
# repr 自动调用 __repr__
>>> print(mab)
MyAddBothstr(3)
>>> str(mab),repr(mab)
('MyAddBothstr(3)', 'MyAddBothrepr(3)')

1.1.2 自定义repr

当print对象在顶层时会调用自定义__str__,非顶层时调用默认调用内容或调用__repr__。

所以,建议自定义__repr__,来统一拦截print(),str(),repr()操作。

python 复制代码
>>> class MyPrintStr:
    def __init__(self,val):
        self.val=val
    def __str__(self):
        return str(self.val)
>>> class MyPrintRepr:
    def __init__(self,val):
        self.val=val
    def __repr__(self):
        return str(self.val)
# 实例非顶层时print时用默认打印,或者repr,而不会用str
>>> mpsl=[MyPrintStr(1),MyPrintStr(2)]
>>> mprl=[MyPrintRepr(1),MyPrintRepr(2)]
>>> print(mpsl)
[<__main__.MyPrintStr object at 0x009F8370>, <__main__.MyPrintStr object at 0x009F8430>]
>>> print(mprl)
[1, 2]

1.2 重载右侧和原处加法

1.2.1 radd

实例在加号左侧,自动调用 add

实例在加号右侧,自动调用 radd

python 复制代码
>>> class MyRadd:
    def __init__(self,val):
        self.val = val
    def __add__(self,other):
        print('add',self.val,other)
        return self.val+other
    def __radd__(self,other):
        print('radd',self.val,other)
        return other+self.val
>>> x=MyRadd(8)
>>> y=MyRadd(9)
# 实例 在加号左边, 自动调用 __add__
>>> x+1
add 8 1
9
# 实例 在加号右边, 自动调用 __radd__
>>> 1+y
radd 9 1
10
# 两个实例相加时, 先调用 add 再调用 radd
>>> x+y
add 8 <__main__.MyRadd object at 0x00A23A30>
radd 9 8
17

# return 类实例时,需要类型测试isinstance,避免嵌套循环
>>> class MyRaddIf:
    def __init__(self,val):
        self.val = val
    def __add__(self,other):
        print('add',self.val,other)
        if isinstance(other,MyRaddIf):
            other=other.val
        return MyRaddIf(self.val+other)
    def __radd__(self,other):
        print('radd',self.val,other)
        return MyRaddIf(other+self.val)
    def __repr__(self):
        return '<MyRaddIf:{}>'.format(self.val)

    
>>> x=MyRaddIf(8)
>>> y=MyRaddIf(9)
>>> print(x+10)
add 8 10
<MyRaddIf:18>
>>> print(10+y)
radd 9 10
<MyRaddIf:19>
>>> z=x+y
add 8 <MyRaddIf:9>
>>> print(z)
<MyRaddIf:17>
#>>> print(z)#注释 if isinstance(other,MyRaddIf) 时,发生嵌套
#<MyRaddIf:<MyRaddIf:17>>
>>> print(z+10)
add 17 10
<MyRaddIf:27>
>>> print(z+z)
add 17 <MyRaddIf:17>
<MyRaddIf:34>
>>> class MyRadd:
    def __init__(self,val):
        self.val = val
    def __add__(self,other):
        print('add',self.val,other)
        return self.val+other
>>> x=MyRadd(8)
>>> x+1
add 8 1
9
# 没有radd时,实例在右侧会报错
>>> 1+x
Traceback (most recent call last):
  File "<pyshell#127>", line 1, in <module>
    1+x
TypeError: unsupported operand type(s) for +: 'int' and 'MyRadd'

1.2.2 iadd

python的+=优先调用__iadd___,没有再调用_add__。

python 复制代码
>>> class MyIadd:
    def __init__(self,val):
        self.val=val
    def __iadd__(self,other):
        self.val+=other
        return self
# += 调用 __add__
>>> x=MyIadd(5)
>>> x+=1
>>> x.val
6
>>> class MyIadd:
    def __init__(self,val):
        self.val=val
    def __add__(self,other):
        self.val+=other
        return self
# += 调用 __add__
>>> x=MyIadd(5)
>>> x+=1
>>> x.val
6
>>> class MyIadd:
    def __init__(self,val):
        self.val=val
    def __add__(self,other):
        print('__add__')
        self.val+=other
        return self
    def __iadd__(self,other):
        print('__iadd__')
        self.val+=other
        return self
# += 优先调用 __iadd__
>>> x=MyIadd(5)
>>> x+=1
__iadd__
相关推荐
何大春9 分钟前
【弱监督语义分割】Self-supervised Image-specific Prototype Exploration for WSSS 论文阅读
论文阅读·人工智能·python·深度学习·论文笔记·原型模式
在下不上天17 分钟前
Flume日志采集系统的部署,实现flume负载均衡,flume故障恢复
大数据·开发语言·python
SEVEN-YEARS21 分钟前
深入理解TensorFlow中的形状处理函数
人工智能·python·tensorflow
EterNity_TiMe_25 分钟前
【论文复现】(CLIP)文本也能和图像配对
python·学习·算法·性能优化·数据分析·clip
Suyuoa37 分钟前
附录2-pytorch yolov5目标检测
python·深度学习·yolo
好看资源平台2 小时前
网络爬虫——综合实战项目:多平台房源信息采集与分析系统
爬虫·python
进击的六角龙2 小时前
深入浅出:使用Python调用API实现智能天气预报
开发语言·python
檀越剑指大厂2 小时前
【Python系列】浅析 Python 中的字典更新与应用场景
开发语言·python
湫ccc2 小时前
Python简介以及解释器安装(保姆级教学)
开发语言·python
孤独且没人爱的纸鹤2 小时前
【深度学习】:从人工神经网络的基础原理到循环神经网络的先进技术,跨越智能算法的关键发展阶段及其未来趋势,探索技术进步与应用挑战
人工智能·python·深度学习·机器学习·ai