函数重写
函数重写:在自定义的类内加添相应的方法,让自定义的类创建的实例能够像内建对象一样进行内建的函数操作
对象转字符串函数的重写:
__repr__ repr() 函数重写
__str__ str() 函数重写
说明:
1. str(obj) 函数先查找obj.__str__()方法,调用此方法并返回结果
2. 如果obj.__str__()方法不存在,则调用obj.__repr__() 方法 并返回结果
3. 如果obj.__repr__方法不存在,则调用object类的__repr__实例方法显示<__main__.xxxxobject at 0xXXXXXXXX> 格式的字符串
# mynumber2.py
class MyNumber(object):
'''此类用于定义一个自定义的数字类型'''
def __init__(self, value):
self.data = value # data数据
def __str__(self):
'''重写object类中的__str__(obj)'''
print("MyNumber.__str__被调用")
return "数字%d" % self.data
def __repr__(self):
return "MyNumber(%d)" % self.data
n1 = MyNumber(100)
s1 = str(n1) # s1 = n1.__str__()
print(s1)
s2 = repr(n1) # s2 = n1.__repr__()
print(s2)
内建函数的重写
__abs__ abs(obj) 函数重写
__len__ len(obj) 函数重写
__reversed__ reversed(obj) 函数重写
__round__ round(obj) 函数重写
# mylist.py
class MyList:
'''创建一个自定义列表类, 此MyList内部用列表来存储信息'''
def __init__(self, iterable=()):
self.data = [x for x in iterable]
def __repr__(self):
return "MyList(%s)" % self.data
def __len__(self):
'''方法必须反回整数'''
return self.data.__len__()
# return len(self.data)
def __abs__(self):
'''此方法实现把self的所有元素取绝对值后返回全为正数的自定义列表MyList'''
lst = [abs(x) for x in self.data]
return MyList(lst) # 创建新的MyList
myl = MyList([1, -2, 3, -4])
print(myl)
print("myl 的长度是:", len(myl)) # myl.__len__()
print(abs(myl)) # MyList([1, 2, 3, 4])
# myl2 = MyList()
# print(myl2)
数值转换函数重写
__complex__ complex(obj) 函数重写
__int__ int(obj) 函数重写
__float__ float(obj) 函数重写
__bool__ bool(obj) 函数重写
# myinteger.py
class MyInteger:
def __init__(self, value):
self.data = int(value)
def __int__(self):
'''此方法必须返回整数'''
return self.data
def __float__(self):
return float(self.data)
a1 = MyInteger("100")
i = int(a1) # 将MyInteger类型转为整数
print(i)
f = float(a1) # a1.__float__()
print(f)
c = complex(a1) # a1.__complex__()
print(c)
b = bool(a1) # a1.__bool__()
print(b)
运算符重载 overload
什么是运算符重载
让自定义的类生成的对象(实例) 能够使用运算符进行操作
作用:
让程序简洁易读
对自定义的对象将运算符赋序新的规则
说明:
运算符重载方法的参数的固定的含义,不建议改变运算符的原的含义
算术运算符重载方法
__add__(self,rhs) self + rhs 加法
__sub__(self,rhs) self - rhs 减法
__mul__(self,rhs) self * rhs 乘法
__truediv__(self,rhs) self / rhs 除法
__floordiv__(self,rhs) self // rhs 地板除
__mod__(self,rhs) self % rhs 求余
__pow__(self,rhs) self ** rhs 幂运算
注: rhs (right hand side ) 右手边
# mynumber.py
# 此示例示意 运算符重载
class MyNumber:
'自定义数字'
def __init__(self, value):
self.data = value
def __repr__(self):
return "MyNumber(%d)" % self.data
def __add__(self, other):
'''加号运算符的重载方法'''
print("__add__被调用")
v = self.data + other.data
return MyNumber(v) # 创建一个新对象
def __sub__(self, rhs):
return MyNumber(self.data - rhs.data)
n1 = MyNumber(100)
n2 = MyNumber(200)
# n3 = n1.__add__(n2) # MyNumber(300)
n3 = n1 + n2 # 等同于n1.__add__(n2)
print(n1, "+", n2, "=", n3)
n4 = n1 - n2
print(n1, "-", n2, "=", n4)
反向算术运算符重载方法
__radd__(self,lhs) lhs + self 加法
__rsub__(self,lhs) lhs - self 减法
__rmul__(self,lhs) lhs * self 乘法
__rtruediv__(self,lhs) lhs / self 除法
__rfloordiv__(self,lhs) lhs // self 地板除
__rmod__(self,lhs) lhs % self 求余
__rpow__(self,lhs) lhs ** self 幂运算
注: lhs (left hand side ) 左手边
# 此示例示意反向算术运算符的重载方法
class MyList:
def __init__(self, iterable=()):
self.data = list(iterable)
def __repr__(self):
return "MyList(%s)" % self.data
def __add__(self, rhs):
return MyList(self.data + rhs.data)
def __mul__(self, rhs):
print("__mul__被调用")
return MyList(self.data * rhs)
def __rmul__(self, lhs):
print("__rmul__被调用")
return MyList(self.data * lhs)
L1 = MyList(range(1, 4))
L2 = MyList([4, 5, 6])
L5 = L1 * 3 # L1.__mul__(3)
print(L5) # MyList([1,2,3,1,2,3,1,2,3])
L6 = 3 * L1 # L1.__rmul__(3)
print(L6)
复合赋值算术运算符的重载
以复合赋值算术运算符 x += y 为例,此运算符会优先调用x.__iadd__(y) 方法,如果没有__iadd__方法时会将复合赋值运算符拆解为 x = x + y, 然后调用 x = x.__add__(y) 方法,如果再不存在__add__方法,则会触发TypeError异常
__iadd__(self, rhs) self += rhs 加法
__isub__(self, rhs) self -= rhs 减法
__imul__(self, rhs) self *= rhs 乘法
__itruediv__(self, rhs) self /= rhs 除法
__ifloordiv__(self, rhs) self //= rhs 地板除
__imod__(self, rhs) self %= rhs 求余
__ipow__(self, rhs) self **= rhs 幂运算
注: rhs (right hand side ) 右手边
# 此示例示意复合赋值算术运算符的重载方法
class MyList:
def __init__(self, iterable=()):
self.data = list(iterable)
def __repr__(self):
return "MyList(%s)" % self.data
def __add__(self, rhs):
print("__add__方法被调用")
return MyList(self.data + rhs.data)
def __iadd__(self, rhs):
print("__iadd__被调用")
self.data.extend(rhs.data)
return self
L1 = MyList(range(1, 4))
L2 = MyList([4, 5, 6])
print(id(L1))
L1 += L2 # L1.__iadd__(L2)
print(id(L1))
print("L1=", L1)
print("L2=", L2)
比较运算符的重载:
__lt__(self, rhs) self < rhs 小于
_le_(self, rhs) self <= rhs 小于等于
_gt_(self, rhs) self > rhs 大于
_ge_(self, rhs) self >= rhs 大于等于
_eq_(self, rhs) self == rhs 等于
_ne_(self, rhs) self != rhs 不等于
注: 比较运算符通常返回布尔值True 或 False
位运算符重载
_and_(self, rhs) self & rhs 位与
_or_(self, rhs) self | rhs 位或
_xor_(self, rhs) self ^ rhs 位异或
_lshift_(self, rhs) self << rhs 左移
_rshift_(self, rhs) self >> rhs 右移
反向位运算符重载
_rand_(self, lhs) lhs & self 位与
_ror_(self, lhs) lhs | self 位或
_rxor_(self, lhs) lhs ^ self 位异或
_rlshift_(self, lhs) lhs << self 左移
_rrshift_(self, lhs) lhs >> self 右移
复合赋值位运算符重载
_iand_(self, rhs) self &= rhs 位与
_ior_(self, rhs) self |= rhs 位或
_ixor_(self, rhs) self ^= rhs 位异或
_ilshift_(self, rhs) self <<= rhs 左移
_irshift_(self, rhs) self >>= rhs 右移
一元运算符的重载
_neg_(self) - self 负号
__pos__(self) + self 正号
_invert_(self) ~ self 取反
# 此示例示意复合赋值算术运算符的重载方法
class MyList:
def __init__(self, iterable=()):
self.data = list(iterable)
def __repr__(self):
return "MyList(%s)" % self.data
def __neg__(self):
'''重载负号运算符'''
# L = [-x for x in self.data]
# L = (-x for x in self.data)
L = map(lambda x:-x, self.data)
return MyList(L)
def __pos__(self):
'''重载+号运算符'''
L = (abs(x) for x in self.data)
return MyList(L)
L1 = MyList([1, -2, 3, -4, 5])
L2 = -L1
print(L2) # MyList([-1, 2, -3, 4, -5])
# L3 = +L1
# print(L3) # MyList([1, 2, 3, 4, 5])
in / not in 运算符重载
# 此示例示意in /not in 运算符重载方法
class MyList:
def __init__(self, iterable=()):
self.data = list(iterable)
def __repr__(self):
return "MyList(%s)" % self.data
def __contains__(self, e):
'重载in 运算符,只需要判断 e是否在self里'
return e in self.data
L1 = MyList([1, -2, 3, -4, 5])
print(3 in L1) # True
print(3 not in L1) # False
print(4 not in L1) # True
print(4 in L1) # False
索引和切片运算符的重载
_getitem_(self, i) x=self[i] 取值
_setitem_(self, i, v) self[i]=v 赋值
_delitem_(self, i) del self[i] 删除
# 此示例示意 索引和切片 [] 运算符重载方法
class MyList:
def __init__(self, iterable=()):
self.data = list(iterable)
def __repr__(self):
return "MyList(%s)" % self.data
def __getitem__(self, i):
print("__getitem__被调用, i=", i)
return self.data[i]
def __setitem__(self, i, v):
print("__setitem__: i=", i, "v=", v)
# print("嘿嘿!")
self.data[i] = v
def __delitem__(self, i):
print("__delitem__被调用 i=", i)
del self.data[i]
L1 = MyList([1, -2, 3, -4, 5])
x = L1[2] # x = L1.__getitem__(2)
print(x)
L1[1] = 2.2 # L1.__setitem(1, 2.2)
print(L1)
del L1[3] # L1.__delitem(3)
print(L1)
slice构造函数:
作用:
用于创建一个slice切片对象,此对象存储一个切片的起始值,终止值,步长信息
格式:
slice(start=None, stop=None, step=None)
slice的属性:
s.start 切片的起始值,默认为None
s.stop 切片的终止值,默认为None
s.step 切片的步长,默认为None
# 此示例示意 切片 [] 运算符重载方法
class MyList:
def __init__(self, iterable=()):
self.data = list(iterable)
def __repr__(self):
return "MyList(%s)" % self.data
def __getitem__(self, i):
if type(i) is int:
return self.data[i]
elif type(i) is slice: #i 绑定的时slice对象 i = slice(1,None,2)
print("起始值:", i.start)
print("终止值:", i.stop)
print("步长:", i.step)
return self.data[i]
L1 = MyList([1, -2, 3, -4, 5])
print(L1) #调用MyList类中的__repr__
x = L1[1::2] # L1.__getitem__(slice(1,None,2)) 此时x属于list类
print(x) # [-2, -4] #会调用list类中的__repr__