您的位置:首页技术文章
文章详情页

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

【字号: 日期:2022-06-16 17:26:30浏览:4作者:猪猪
目录一、高级异常二、环境管理器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 ??/p>

注: 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 ??/p>

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 ??/p>

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 selfL1 = MyList([1, 2, 3]) # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaL2 = MyList([4, 5, 6]) # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaL1 += 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 = -L1print(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 Truereturn FalseL1 = 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 TypeErrorreturn 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 KeyErrorreturn self.data[i]L1 = MyList([1, -2, 3, -4, 5, -6])print(L1[::2]) # 等同于调用L1[slice(None, None, 2)]

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

标签: Python 编程
相关文章: