zoukankan      html  css  js  c++  java
  • day21学习笔记运算符重加载


    day20笔记 :
      对象的属性管理函数
        getattr(obj, name[,default])
        hasattr(obj, name)
        setattr(obj, name, value)
        delattr(obj, name)
      示例:
        class Dog:
           pass
        d = Dog()
        d.color = "白色"
        c = getattr(d, "color")  # d.color
        hasattr(d,"color") # True
        setattr(d,'kinds', '导盲犬')
        delattr(d, 'kinds')


    异常(高级)
      回顾:
        try-except
        try-finally
        raise
        assert

    with语句
      语法:
        with 表达式1 [as 变量1],表达式2 [as 变量2], ... :
           语句块
      作用:
        使用对资源进行访问的场合,确保使用过程中,不算是否发生异常,都会执行必须的'清理'操作,并释放资源.
          如: 文件使用后自动关闭,线程中锁的自动获取和释放等(线程后面会学)
      说明:
        with语句并不会改变异常的状态(同try-finally类似)

      示例见:
      

    # with.py
    try:
        f = open("text.txt", 'w')
        try:
            s = int(input("请输入整数:"))  #故意制造异常
    
            f.write("hello")
        finally:
            f.close()
    except OSError:
        print("文件打开失败")
    except: 
        print("读取数据失败")
    # with.py
    try:
        # 用with语句实现
        # f = open("text.txt", 'w')
        with open("text.txt", 'w') as f:
            s = int(input("请输入整数:"))  #故意制造异常
    
            f.write("hello")
    except OSError:
        print("文件打开失败")
    except: 
        print("写入数据失败")

    环境管理器:
      1. 类内有__enter__和 __exit__实例方法的类创建的实例被称为环境管理器
      2. 能够用with进行管理的对象必须是环境管理器
      3. __enter__方法将在进入with语句时被调用,且返回由as 变量 管理的对象
      4. __exit__方法将在离开with语句时被调用,且可以用形参来判断离开with语句时的状态

      示例见:
        

    # context.py
    
    # 此示例示意自定义用 with 管理的对象
    class A:
        '''此类的对象将可用于with语句中'''
        def __enter__(self):
            print("已经进入到了with语句的内部")
            return self  #把自己返回由as 来绑定
        def __exit__(self, e_t, e_v, e_tb):
            ''' e_t 用来绑定异常类型
                e_v用来绑定异常对象
                e_tb_用来绑定追踪对象
                在没有异常时,三个形参都绑定None
            '''
            if e_t is None:
                print("已正常离开with语句")
            else:
                print("是在出现异常时走异常流程离开的with语句")
    
    with A() as a:
        print('这是with语句内部的print')
        int(input("请输入整数: "))


    运算符重载 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
            obj = MyNumber(v)  # 创建一个新对象
            return obj
        
        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)

    练习:
      实现两个自定义的列表相加操作
        class MyList:
            ...  # 此处代码自己实现
       
        L1 = MyList(range(1, 4))
        L2 = MyList([4, 5, 6])
        L3 = L1 + L2
        print(L3)  # MyList([1, 2, 3, 4, 5, 6])
        L4 = L2 + L1
        print(L4)  # MyList([4, 5, 6, 1, 2, 3])
        L5 = L1 * 3
        print(L5)  # MyList([1,2,3,1,2,3,1,2,3])

    反向算术运算符的重载:
      当运算符的左侧为内建类型,右侧为自定义类型进行算术运算时,会出现TypeErorr错误
      因无法修改内建类型的代码实现运算符重载,此时需要使用反向算术运算符的重载来完成重载

    反向算术运算符重载方法
    方法名               运算符和表达式    说明
    __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 ) 左手边

    复合赋值算术运算符的重载
      以复合赋值算术运算符 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 ) 右手边

    比较运算符的重载:
    方法名               运算符和表达式    说明
    __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)rhs  >> 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 类名:
          def __xxx__(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)
    
    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 运算符重载
      方法格式:
        def __contains__(self, e):
           ...
     
      #  e in self
    示例见:

    # 此示例示意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)
    # 此示例示意 切片 [] 运算符重载方法
    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)
            if type(i) is int:
                print("您正在执行索引操作")
            elif type(i) is slice:
                print("您正在执行切片操作")
                print("起始值:", i.start)
                print("终止值:", i.stop)
                print("步长:", i.step)
    
            return self.data[i]
    
    
    L1 = MyList([1, -2, 3, -4, 5])
    x = L1[1::2]
    print(x)  # [-2, -4]
    
    x = L1[2]
    print(x)  # 3

    slice构造函数:
      作用:
        用于创建一个slice切片对象,此对象存储一个切片的起始值,终止值,步长信息
      格式:
        slice(start=None, stop=None, step=None)
    slice的属性:
      s.start  切片的起始值,默认为None
      s.stop  切片的终止值,默认为None
      s.step  切片的步长,默认为None

    特性属性 @property
      实现其它语言所拥有的 getter 和 setter 功能

      作用:
        用来模拟(虚拟)一个属性
        通过@property 装饰器可以对模拟的属性赋值和取值加以控制
      示例见:
        

    # property.py
    
    # 此示例示意用@property 来实现getter和 setter
    
    class Student:
        def __init__(self, s):
            self.__score = s  # 成绩
    
        def get_score(self):
            '''getter'''
            return self.__score
    
        def set_score(self, s):
            '''setter'''
            assert 0 <= s <= 100, "成绩超出范围"
            self.__score = s
    
    s1 = Student(59)
    print(s1.get_score())
    # print(s1.score)  # 取值
    s1.set_score(999999999999)
    # s1.score = 999999999999   # 赋值
    # property.py
    
    # 此示例示意用@property 来实现getter和 setter
    
    class Student:
        def __init__(self, s):
            self.__score = s  # 成绩
    
        @property
        def score(self):
            '''getter'''
            print("调用getter")
            return self.__score
    
        @score.setter
        def score(self, s):
            '''setter'''
            print("调用setter")
            assert 0 <= s <= 100, "成绩超出范围"
            self.__score = s
    
    s1 = Student(59)
    print(s1.score)  # 取值
    # s1.score = 999999999999 #触发AssertionError
    s1.score = 80   # 赋值
    print(s1.score)
  • 相关阅读:
    python接口自动化测试十三:url编码与解码
    python接口自动化测试十二:对返回的json的简单操作
    python接口自动化测试十一:传参数:data与json
    python接口自动化测试九:重定向相关
    python接口自动化测试十:字典、字符串、json之间的简单处理
    python接口自动化测试八:更新Cookies、session保持会话
    python接口自动化测试七:获取登录的Cookies
    python接口自动化测试六:时间戳,防重复处理
    python接口自动化测试五:乱码、警告、错误处理
    python接口自动化测试四:代码发送HTTPS请求
  • 原文地址:https://www.cnblogs.com/sky-ai/p/9732812.html
Copyright © 2011-2022 走看看