一、高级异常
回顾异常相关的语句:
try-except:用来捕获异常的通知
try-finally:用来做一定要做的事
reise:用来发生异常通知
assert:用来根据条件来发出AssertionError类型的异常通知
with语句:
语句: with 表达式1 [as 变量1],表达式2 [as 变量2]:
语句块
作用:使用于对资源进行访问的场合,确保使用过程中不管是否发生异常,都会执行必须的'清理'操作,并释放资源
如:文件使用后自动关闭;线程中锁定的自动获取和释放等
用with语句代替try-finally语句
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
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语句时是否有异常发生并做出相应的处理
1
2
3
4
5
6
7
8
9
10
11
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
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) 右手边
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
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)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
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 冪
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
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 冪
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
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):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
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 成员运算
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
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语句删除索引等
作用:
让自定义的类型的对象能够支持索引和切片操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
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 高级异常 运算符重载的资料请关注服务器之家其它相关文章!
原文链接:https://www.cnblogs.com/LXP-Never/p/9385213.html