解析python高级异常和运算符重载

编辑: admin 分类: python 发布时间: 2021-12-24 来源:互联网
目录
  • 一、高级异常
  • 二、环境管理器
    • 2.1、对象的属性管理函数
  • 三、运算符重载
    • 3.1、算术运算符的重载
  • 四、反向算术运算符的重载
    • 五、复合赋值算术运算符的重载
      • 六、比较运算符的重载
        • 七、位运算符重载
          • 八、反向位运算符重载
            • 九、复合赋值位运算符重载
              • 十、一元运算符的重载
                • 十一、in / not in 运算符的重载
                  • 十二、索引和切片运算符的重载
                    • 十三、slice 构造函数

                      一、高级异常

                      回顾异常相关的语句:

                      try-except:用来捕获异常的通知

                      try-finally:用来做一定要做的事

                      reise:用来发生异常通知

                      assert:用来根据条件来发出AssertionError类型的异常通知

                      with语句:

                      语句: with 表达式1 [as 变量1],表达式2 [as 变量2]:

                               语句块

                      作用:使用于对资源进行访问的场合,确保使用过程中不管是否发生异常,都会执行必须的'清理'操作,并释放资源

                      如:文件使用后自动关闭;线程中锁定的自动获取和释放等

                      用with语句代替try-finally语句

                      def read_from_file(filename='info.txt'):
                           try:
                               with open(filename) as f:
                                   print("正在读取文件")
                                   n = int(f.read())
                                   print('n=', n)
                                   print('文件已经关闭')
                               # f = open(filename)
                               # try:
                               #     print("正在读取文件")
                               #     n = int(f.read())
                               #     print("n=", n)
                               # finally:
                               #     f.close()
                               #     print("文件已经关闭")
                           except OSError:
                               print("文件打开失败")
                       
                       
                       read_from_file()

                      二、环境管理器

                      1、类内有__enter__和__exit__实例方法的类被称为环境管理器

                      2、能够用with语句管理的对象必须是环境管理器

                      3、 __enter__方法将在进入with语句时被调用,并返回由as变量管理的对象

                      4、__exit__将在离开with语句时被调用,且可以用参数来判断在离开with语句时是否有异常发生并做出相应的处理

                      class A:
                           def __enter__(self):
                               print("已进入with语句")
                               return self  # 返回的对象将由 as绑定
                       
                           def __exit__(self, exc_type, exc_val, exc_tb):
                               print("已离开with语句")
                       # a = A()
                       with A() as a:
                           print("这是with语句内的一条语句")
                           int(input("请输入整数: "))

                      已进入with语句

                      这是with语句内的一条语句

                      请输入整数: 2

                      2.1、对象的属性管理函数

                      1、getattr(obj, name[, default])从一个对象得到对象的属性;getattr(x, 'y')等同于x.y;当属性不存在时,如果给出default参数,则返回default,如果没有给出default则产生一个AttributeError错误

                      2、hasattr(obj, name)用给定的name返回对象obj是否有此属性,此种做法可以避免在getattr(obj, name)时引发错误

                      3、setattr(obj, name, value)给对象obj的名为name的属性设置相应的值value, set(x,'y', v) 等同于 x.y = v

                      4、delattr(obj, name)删除对象obj中的name属性,delattr(x, 'y') 等同于 del x.y

                      class Car:
                           def __init__(self, c, b):
                               self.color, self.brand = c, b
                       
                           def get_car_attr(self, attr_name):
                               '''此方法用于获取对象的属性,如果属性名attr_name
                               在此对象内不存在则返回 None
                               '''
                               return getattr(self, attr_name, None)
                       
                       c1 = Car('黑色', 'Benz')
                       v = c1.get_car_attr('color')
                       # try:
                       #     v = c1.__dict__['aaaaa']
                       # except KeyError:
                       #     v = None
                       if v is None:
                           print("没有颜色属性")
                       else:
                           print("颜色是:", v)
                      
                      getatter(obj,name[,default])

                      三、运算符重载

                      让自定义的类生成的对象(实例)能够使用运算符进行操作

                      作用:让自定义的类的实例像内建对象一样能够运行运算符操作,让程序简单易读,对自定义的对象,将运算符赋予新的运算规则

                      3.1、算术运算符的重载

                      __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 hands side) 右手边

                      class MyNumber:
                           def __init__(self, v):
                               self.data = v
                       
                           def __repr__(self):
                              return 'MyNumber(%d)' % self.data
                       
                           # def myadd(self, other):
                           #     v = self.data + other.data
                           #     return MyNumber(v)
                       
                           def __add__(self, other):
                              print("__add__被调用")
                               v = self.data + other.data
                               return MyNumber(v)
                       
                           def __sub__(self, rhs):
                               v = self.data - rhs.data
                               return MyNumber(v)
                       
                       n1 = MyNumber(100)
                       n2 = MyNumber(200)
                       # n3 = n1.myadd(n2)
                       # n3 = n1.__add__(n2)
                       n3 = n1 + n2  # __add__被调用
                       print(n3)   # MyNumber(300)
                       n4 = n3 - n2
                       print(n4)   # MyNumber(100)
                      class MyList:
                           def __init__(self, iterable):
                               self.data = list(iterable)
                       
                           def __add__(self, rhs):
                               return MyList(self.data + rhs.data)
                       
                           def __repr__(self):
                               return 'MyList(%r)' % self.data
                      
                           def __mul__(self, rhs):  # rhs 绑定整数
                               return MyList(self.data * rhs)
                       
                       L1 = MyList([1, 2, 3])
                       L2 = MyList([4, 5, 6])
                       L3 = L1 + L2  # 等同于L1.__add__(L2)
                       print(L3)  # MyList([1,2,3,4,5,6])
                       L4 = L2 + L1  # 等同于L2.__add__(L1)
                       print(L4)  # MyList([4,5,6,1,2,3])
                       L5 = L1 * 2  # L1.__mul__(2)
                       print(L5)  # MyList([1,2,3,1,2,3])

                      四、反向算术运算符的重载

                      __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   冪

                      class MyList:
                           def __init__(self, iterable):
                               self.data = list(iterable)
                       
                           def __add__(self, rhs):
                               return MyList(self.data + rhs.data)
                       
                           def __repr__(self):
                              return 'MyList(%r)' % self.data
                       
                           def __mul__(self, rhs):  # rhs 绑定整数
                               print('__mul__被调用')
                               return MyList(self.data * rhs)
                           def __rmul__(self, lhs):
                               print('__rmul__被调用')
                               return MyList(self.data * lhs)
                       
                       L1 = MyList([1, 2, 3])
                       L2 = MyList([4, 5, 6])
                       L5 = L1 * 2  # L1.__mul__(2)
                       print(L5)  # MyList([1,2,3,1,2,3])
                       
                       L6 = 2 * L1  # 2.__mul__(L1)
                       print(L6)

                      五、复合赋值算术运算符的重载

                      __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    冪

                      class MyList:
                          def __init__(self, iterable):
                              print("aaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
                              self.data = list(iterable)
                      
                          def __add__(self, rhs):
                              print('__add__被调用')
                              return MyList(self.data + rhs.data)
                      
                          def __repr__(self):
                              return 'MyList(%r)' % self.data
                      
                          def __iadd__(self, rhs):
                              print("__iadd__被调用!!!!")
                              self.data.extend(rhs.data)
                              return self
                      
                      L1 = MyList([1, 2, 3])  # aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
                      L2 = MyList([4, 5, 6])  # aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
                      L1 += L2  # 当没有__iadd__方法时,等同于调用L1 = L1 + L2    __iadd__被调用!!!!
                      print(L1)   # MyList([1, 2, 3, 4, 5, 6])

                      六、比较运算符的重载

                      __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

                      七、位运算符重载

                      __invert__(self)      ~ self      取反(一元运算符)
                      __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 类名:
                      def __xxx__(self):

                      class MyList:
                          def __init__(self, iterable):
                              print("__init__被调用")
                              self.data = list(iterable)
                      
                          def __repr__(self):
                              return 'MyList(%r)' % self.data
                      
                          def __neg__(self):
                              '''此方法用来制定 - self 返回的规则'''
                              # L = [-x for x in self.data]
                              L = (-x for x in self.data)
                              return MyList(L)
                      
                      L1 = MyList([1, -2, 3, -4])
                      L2 = -L1
                      print(L2)

                      运算符重载说明:

                      运算符重载不能改变运算符的优先级

                      Python类名最好用驼峰命名法:

                      • MyList MyRange 大驼峰(所有单词首字母大写,其余小写)
                      • getStudentAge 小驼峰(第一个单词首字母小写,其它首字母大写)

                      十一、in / not in 运算符的重载

                      重载方法:

                      __contains__(self, e) e in self 成员运算

                      class MyList:
                          def __init__(self, iterable):
                              print("__init__被调用")
                              self.data = list(iterable)
                      
                          def __repr__(self):
                              return 'MyList(%r)' % self.data
                      
                          def __contains__(self, e):
                              '''此方法用来实现 in / not in 运算符的重载'''
                              print("__contains__被调用")
                              for x in self.data:
                                  if x == e:
                                      return True
                              return False
                      
                      
                      L1 = MyList([1, -2, 3, -4])
                      if -2 in L1:
                          print('-2 在 L1 中')
                      else:
                          print('-2 不在 L1中')
                      
                      
                      # 当MyList的类内重载了__contains__方法,则not in也同时可用
                      if -3 not in L1:
                          print("-3 不在 L1中")
                      else:
                          print('-3 在 L2中')

                      十二、索引和切片运算符的重载

                      __getitem__(self, i)     x = self[i] 索引/切片取值
                      __setitem__(self, i, v)      self[i] = v 索引/切片赋值
                      __delitem__(self, i)        del self[i] del语句删除索引等

                      作用:

                      让自定义的类型的对象能够支持索引和切片操作

                      class MyList:
                          def __init__(self, iterable):
                              print("__init__被调用")
                              self.data = list(iterable)
                      
                          def __repr__(self):
                              return 'MyList(%r)' % self.data
                      
                          def __getitem__(self, i):
                              print("__getitem__被调用, i=", i)
                              # if type(i) is not int:
                              #     raise TypeError
                              return self.data[i]
                      
                          def __setitem__(self, i, v):
                              print("__setitem__被调用, i=", i, 'v =', v)
                              self.data[i] = v  # 修改data绑定的列表
                      
                      
                      L1 = MyList([1, -2, 3, -4])
                      v = L1[-1]
                      print(v)
                      
                      L1[1] = 2  # 等同于调用 L1.__setitem__(1, 2)
                      print(L1)
                      
                      # 以下操作会出错
                      # print(L1[100000000000])
                      # print(L1['hello'])

                      十三、slice 构造函数

                      作用:用于创建一个Slice切片对象, 此对象存储一个切片的起始值,终止值和步长信息

                      slice(start, stop=None, step=None) 创建一个切片对象

                      slice的对象的属性:

                      • s.start 切片起始值,默认为None
                      • s.stop 切片终止值,默认为None
                      • s.step 切片步长 ,默认为None
                      class MyList:
                          def __init__(self, iterable):
                              print("__init__被调用")
                              self.data = list(iterable)
                      
                          def __repr__(self):
                              return 'MyList(%r)' % 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)
                              else:
                                  raise KeyError
                              return self.data[i]
                      
                      
                      L1 = MyList([1, -2, 3, -4, 5, -6])
                      
                      print(L1[::2])  # 等同于调用L1[slice(None, None, 2)]

                      以上就是解析python高级异常和运算符重载的详细内容,更多关于python 高级异常 运算符重载的资料请关注hwidc其它相关文章!