函数重构

函数重写

函数重写:在自定义的类内加添相应的方法,让自定义的类创建的实例能够像内建对象一样进行内建的函数操作

对象转字符串函数的重写:

__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__
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值