您好,登錄后才能下訂單哦!
這篇文章主要講解了“如何理解python高級異常和運算符重載”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“如何理解python高級異常和運算符重載”吧!
回顧異常相關的語句:
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
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])
讓自定義的類生成的對象(實例)能夠使用運算符進行操作
作用:讓自定義的類的實例像內建對象一樣能夠運行運算符操作,讓程序簡單易讀,對自定義的對象,將運算符賦予新的運算規則
__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 小駝峰(第一個單詞首字母小寫,其它首字母大寫)
重載方法:
__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(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高級異常和運算符重載這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。