__str__()与__repr__()
这两个特殊方法用于自定义并返回实例对象的字符串表示形式。
- 当调用内置函数str()时并且第一个参数是实例对象时,
如果在实例对象对应的类对象中实现了特殊方法__str__(),在内置函数str的内部会自动调用该方法;
否则,如果在实例对象对应的类对象中实现了特殊方法__repr__(),在内置函数str的内部会自动调用该方法;
否则,会打印实例对象对应的类对象和实例对象在内存中的地址。
#在类对象中实现了特殊方法__repr__()
In [1]: class MyClass2(object):
...: def __repr__(self):
...: return "repr被调用"
...:
In [2]: mc2 = MyClass2()
In [3]: mc2
Out[3]: repr被调用
In [4]: str(mc2)
Out[4]: 'repr被调用'
In [5]: repr(mc2)
Out[5]: 'repr被调用'
#在类对象的内部实现了__str__()特殊方法
In [1]: class MyClass1(object):
...: def __str__(self):
...: return "str被调用"
...: mc1 = MyClass1()
In [2]: mc1
Out[2]: <__main__.MyClass1 at 0x285f5897ba8>
In [3]: str(mc1)
Out[3]: 'str被调用'
In [4]: repr(mc1)
Out[4]: '<__main__.MyClass1 object at 0x00000285F5897BA8>'
- 当调用内置函数repr()时并且第一个参数是实例对象时,
如果在实例对象对应的类对象中实现了特殊方法__repr__(),在内置函数repr的内部会自动调用该方法
In [1]: class MyClass(object):
...: def __str__(self):
...: return "str被调用"
...: def __repr__(self):
...: return "repr被调用"
...: mc = MyClass()
In [2]: mc
Out[2]: repr被调用
In [3]: str(mc)
Out[3]: 'str被调用'
In [4]: repr(mc)
Out[4]: 'repr被调用'
算术运算符重载
标准运算符在默认情况下不能用于自定义类对象的实例对象
In [1]: class MyClass1(object):
...: pass
...: class MyClass2(object):
...: pass
...:
In [2]: print(MyClass1()+MyClass2())
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-19-ce5056f11b9c> in <module>
----> 1 print(MyClass1()+MyClass2())
TypeError: unsupported operand type(s) for +: 'MyClass1' and 'MyClass2'
如果想要算术运算符能够用于自定义类对象的实例对象,需要在类对象中定义实现标准运算符对应的特殊方法:
- +对应的特殊方法为:__add__()和__radd__()
- -对应的特殊方法为:__sub__()和__rsub__()
- *对应的特殊方法为:__mul__()和__rmul__()
- /对应的特殊方法为:__truediv__()和__rtruediv__()
- //对应的特殊方法为:__floordiv__()和__rfloordiv__()
假设两个运算符obj1和obj2,以+为例,对于obj1和obj2,需要在obj1对应的自定义类对象中实现特殊方法__add__(),或在obj2对应的自定义类对象中实现特殊方法__radd__()(r是right的缩写);
因为obj1位于运算符+的左边,所以实现的特殊方法是__add__();
因为obj2位于运算符+的右边,所以实现的特殊方法是__radd__();
class MyClass1(object):
def __add__(self,other):
return "这是__add__+的结果"
class MyClass2(object):
def __radd__(self,other):
return "这是__radd__+的结果"
obj1 = MyClass1()
obj2 = MyClass2()
print(obj1 + obj2)
运行结果:
这是__add__+的结果
class MyClass1(object):
pass
class MyClass2(object):
def __radd__(self,other):
return "这是__radd__+的结果"
obj1 = MyClass1()
obj2 = MyClass2()
print(obj1 + obj2)
运行结果:
这是__radd__+的结果
class MyClass1(object):
def __add__(self,other):
print("特殊方法__add__()被调用")
return NotImplemented
class MyClass2(object):
def __radd__(self,other):
return "这是__radd__+的结果"
obj1 = MyClass1()
obj2 = MyClass2()
print(obj1 + obj2)
运行结果:
特殊方法__add__()被调用
这是__radd__+的结果
class MyClass1(object):
def __add__(self,other):
print("特殊方法__add__()被调用")
return NotImplemented
class MyClass2(object):
def __radd__(self,other):
print("特殊方法__radd__()被调用")
return NotImplemented
obj1 = MyClass1()
obj2 = MyClass2()
print(obj1 + obj2)
运行结果:
特殊方法__add__()被调用
特殊方法__radd__()被调用
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-4-5c0046a39102> in <module>()
9 obj1 = MyClass1()
10 obj2 = MyClass2()
---> 11 print(obj1 + obj2)
TypeError: unsupported operand type(s) for +: 'MyClass1' and 'MyClass2'
在面向对象的学习中,我们还需要掌握一些内置函数:issubstance(),isinstance(),type(),dir(),setattr(),getattr(),hasattr(),delattr(),对它们用法不熟悉的话,可参考我的另一篇博客。查看用法