<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Python 中 with...as的用法


      原文鏈接:

      https://blog.csdn.net/qiqicos/article/details/79200089

      https://blog.csdn.net/elevenqiao/article/details/6796653

       

      with…as,就是個python控制流語句,像 if ,while一樣。
      with…as語句是簡化版的try except finally語句。

       

      那我們先理解一下try…except…finally語句是干啥的。實際上,try…except語句和try…finally語句是兩種語句,用于不同的場景。但是當二者結合在一起時,可以“實現穩定性和靈活性更好的設計”。

      1. try…except語句

      用于處理程序執行過程中的異常情況,比如語法錯誤、從未定義變量上取值等等,也就是一些python程序本身引發的異常、報錯。比如你在python下面輸入 1 / 0:

      1 >>> 1/0
      2 Traceback (most recent call last):
      3   File "<stdin>", line 1, in <module>
      4 ZeroDivisionError: division by zero

      系統會給你一個ZeroDivisionError的報錯。說白了就是為了防止一些報錯影響你的程序繼續運行,就用try語句把它們抓出來(捕獲)。

      try…except的標準格式:

      1 try:  
      2     ## normal block  
      3 except A:  
      4     ## exc A block  
      5 except:  
      6     ## exc other block  
      7 else:  
      8     ## noError block  

      程序執行流程是:

       1 –>執行normal block
       2 –>發現有A錯誤,執行 exc A block(即處理異常)
       3 –>結束
       4 如果沒有A錯誤呢?
       5 –>執行normal block
       6 –>發現B錯誤,開始尋找匹配B的異常處理方法,發現A,跳過,發現except others(即except:),執行exc other block
       7 –>結束
       8 如果沒有錯誤呢?
       9 –>執行normal block
      10 –>全程沒有錯誤,跳入else 執行noError block
      11 –>結束

      Tips: 我們發現,一旦跳入了某條except語句,就會執行相應的異常處理方法(block),執行完畢就會結束。不會再返回try的normal block繼續執行了。

      1 try:
      2     a = 1 / 2 #a normal number/variable
      3     print(a)
      4     b = 1 / 0 # an abnormal number/variable
      5     print(b)
      6     c = 2 / 1 # a normal number/variable
      7     print(c)
      8 except:
      9     print("Error")

      輸出:

      1 0.5
      2 Error

      結果是,先打出了一個0,又打出了一個Error。就是把ZeroDivisionError錯誤捕獲了。

      先執行try后面這一堆語句,由上至下:
      step1: a 正常,打印a. 于是打印出0.5 (python3.x以后都輸出浮點數)
      step2: b, 不正常了,0 不能做除數,所以這是一個錯誤。直接跳到except報錯去。于是打印了Error。
      step3: 其實沒有step3,因為程序結束了。c是在錯誤發生之后的b語句后才出現,根本輪不到執行它。也就看不到打印出的c了

      但這還不是try/except的所有用法

      except后面還能跟表達式的! 所謂的表達式,就是錯誤的定義。也就是說,我們可以捕捉一些我們想要捕捉的異常。而不是什么異常都報出來。

      異常分為兩類:

      • python標準異常
      • 自定義異常

      我們先拋開自定義異常(因為涉及到類的概念),看看except都能捕捉到哪些python標準異常。

       1 try:
       2     a = 1 / 2
       3     print(a)
       4     print(m)  # 此處拋出python標準異常
       5     b = 1 / 0 # 此后的語句不執行
       6     print(b)
       7     c = 2 / 1
       8     print(c)
       9 except NameError:
      10     print("Ops!!")
      11 except ZeroDivisionError:
      12     print("Wrong math!!")
      13 except:
      14     print("Error")

      輸出:

      1 0.5
      2 Ops!!

      當程序執行到print(m)的時候 發現了一個NameError: name 'm' is not defined,于是控制流去尋找匹配的except異常處理語句。發現了第一條匹配,執行對應block。執行完結束。

      2. try…finallly語句

      用于無論執行過程中有沒有異常,都要執行清場工作。

      好的 現在我們看看他倆合在一起怎么用!!

       1 try:  
       2     execution block  ##正常執行模塊  
       3 except A:  
       4     exc A block ##發生A錯誤時執行  
       5 except B:  
       6     exc B block ##發生B錯誤時執行  
       7 except:  
       8     other block ##發生除了A,B錯誤以外的其他錯誤時執行  
       9 else:  
      10     if no exception, jump to here ##沒有錯誤時執行  
      11 finally:  
      12     final block  ##總是執行  

      tips: 注意順序不能亂,否則會有語法錯誤。如果用else就必須有except,否則會有語法錯誤。

       1 try:
       2     a = 1 / 2
       3     print(a)
       4     print(m) # 拋出NameError異常
       5     b = 1 / 0
       6     print(b)  
       7     c = 2 / 1
       8     print(c)
       9 except NameError:
      10     print("Ops!!")  # 捕獲到異常
      11 except ZeroDivisionError:
      12     print("Wrong math!!")
      13 except:
      14     print("Error")
      15 else:
      16     print("No error! yeah!")
      17 finally:      # 是否異常都執行該代碼塊
      18     print("Successfully!")

      輸出:

      1 0.5
      2 Ops!!
      3 Successfully!

      try語句終于搞清楚了! 那么可以繼續with…as的探險了

      3. with…as語句

      with as 語句的結構如下:

      1 with expression [as variable]:
      2     with-block

      看這個結構我們可以獲取至少兩點信息 1. as可以省略 2. 有一個句塊要執行。也就是說with是一個控制流語句,跟if/for/while/try之類的是一類的,with可以用來簡化try finally代碼,看起來可以比try finally更清晰。這里新引入了一個"上下文管理協議"context management protocol,實現方法是為一個類定義__enter__和__exit__兩個函數。with expresion as variable的執行過程是,首先執行__enter__函數,它的返回值會賦給as后面的variable,想讓它返回什么就返回什么,只要你知道怎么處理就可以了,如果不寫as variable,返回值會被忽略。

      然后,開始執行with-block中的語句,不論成功失敗(比如發生異常、錯誤,設置sys.exit()),在with-block執行完成后,會執行__exit__函數。這樣的過程其實等價于:

      1 try:
      2     執行 __enter__的內容
      3     執行 with_block.
      4 finally:
      5     執行 __exit__內容

      只不過,現在把一部分代碼封裝成了__enter__函數,清理代碼封裝成__exit__函數。

      所謂上下文管理協議,其實是指with后面跟的expression。這個expression一般都是一個類的實體。這個類的實體里面要包含有對__enter__和__exit__函數的定義才行。

      除了給類定義一些屬性之外,還可以定義類的方法。也就是允許對類的內容有哪些操作,最直觀的方法就是用dir()函數來看一個類的屬性和方法。比如要查看字符串類有哪些屬性和方法:

      1 >>> dir(str)
      2 ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

      類,除了python內置的,當然還可以自己定義! 所以除了expression表示一些含有這兩種方法的內置類,還可以自己定義類,讓他們含有enter和exit方法。

      可能大家一直奇怪,為什么有的方法,比如上圖中的'split' 'title'什么的都沒有下劃線,而又有很多,,比如__enter__和__exit__要寫下劃線呢?請參考博文http://blog.csdn.net/qiqicos/article/details/79208039

      那么__enter____exit__是怎么用的方法呢?我們直接來看一個例子好了。

       1 class Sample(object):             # object類是所有類最終都會繼承的類
       2     def __enter__(self):          # 類中函數第一個參數始終是self,表示創建的實例本身
       3         print("In __enter__()")
       4         return "Foo"
       5 
       6     def __exit__(self, type, value, trace):
       7         print("In __exit__()")
       8 
       9 
      10 def get_sample():
      11     return Sample()
      12 
      13 
      14 with get_sample() as sample:
      15     print("sample:", sample)
      16 
      17 
      18 print(Sample)    # 這個表示類本身   <class '__main__.Sample'>
      19 print(Sample())  # 這表示創建了一個匿名實例對象 <__main__.Sample object at 0x00000259369CF550>

      輸出結果:

      
      
      1 In __enter__()
      2 sample: Foo
      3 In __exit__()
      4 <class '__main__.Sample'>
      5 <__main__.Sample object at 0x00000226EC5AF550>

      步驟分析:
      –> 調用get_sample()函數,返回Sample類的實例;
      –> 執行Sample類中的__enter__()方法,打印"In__enter_()"字符串,并將字符串“Foo”賦值給as后面的sample變量;
      –> 執行with-block碼塊,即打印"sample: %s"字符串,結果為"sample: Foo"
      –> 執行with-block碼塊結束,返回Sample類,執行類方法__exit__()。因為在執行with-block碼塊時并沒有錯誤返回,所以type,value,trace這三個arguments都沒有值。直接打印"In__exit__()"

      程序有錯的例子:

       1 class Sample:
       2     def __enter__(self):
       3         return self
       4 
       5     def __exit__(self, type, value, trace):
       6         print("type:", type)
       7         print("value:", value)
       8         print("trace:", trace)
       9 
      10     def do_something(self):
      11         bar = 1 / 0
      12         return bar + 10
      13 
      14 
      15 with Sample() as sample:
      16     sample.do_something()

      輸出結果:

      1 type: <class 'ZeroDivisionError'>
      2 value: division by zero
      3 trace: <traceback object at 0x0000019B73153848>
      4 Traceback (most recent call last):
      5   File "F:/機器學習/生物信息學/Code/first/hir.py", line 16, in <module>
      6     sample.do_something()
      7   File "F:/機器學習/生物信息學/Code/first/hir.py", line 11, in do_something
      8     bar = 1 / 0
      9 ZeroDivisionError: division by zero

      步驟分析:
      –> 實例化Sample類,執行類方法__enter__(),返回值self也就是實例自己賦值給sample。即sample是Sample的一個實例(對象);
      –>執行with-block碼塊: 實例sample調用方法do_something();
      –>執行do_something()第一行 bar = 1 / 0,發現ZeroDivisionError,直接結束with-block代碼塊運行
      –>執行類方法__exit__(),帶入ZeroDivisionError的錯誤信息值,也就是type,value, trace,并打印它們。

      posted @ 2021-08-24 10:20  史迪仔_lmj  Views(909)  Comments(0)    收藏  舉報
      主站蜘蛛池模板: 四虎精品永久在线视频| 亚州中文字幕一区二区| 亚洲精品日本一区二区| 国产精品亚洲二区在线播放| 色欧美片视频在线观看| 欧美国产日产一区二区| 99精品国产综合久久久久五月天| 久久久久久国产精品美女| 国产精品系列在线免费看| 人妻有码av中文字幕久久琪| 亚洲精品久久一区二区三区四区| 国产一级特黄高清大片一| 四虎www永久在线精品| 亚洲精品一区二区三区中文字幕| 亚洲永久精品日韩成人av| 精品久久久久久国产| 天堂网av一区二区三区| 永州市| 激情综合五月| 九九热免费公开视频在线| 午夜国产小视频| 久久精品夜色噜噜亚洲aa| 中文字幕国产精品一二区| 白嫩少妇激情无码| 国产欧美国日产高清| 成人国产亚洲精品天堂av| 久久精品国产字幕高潮| 最新的国产成人精品2020| 国产系列丝袜熟女精品视频| 国产稚嫩高中生呻吟激情在线视频| 国产精品视频全国免费观看| 久久无码人妻精品一区二区三区| 在线日韩日本国产亚洲| 和黑人中出一区二区三区| 亚洲欧美日韩愉拍自拍美利坚| 亚洲国产青草衣衣一二三区| 在线免费成人亚洲av| 午夜福利精品国产二区| 男女动态无遮挡动态图| 好男人好资源WWW社区| 国产激情无码一区二区三区|