python-模塊,異常,環境管理器

模塊 Modulepython

  什麼是模塊:編程

    一、模塊是一個包含有一系列數據,函數,類等組成的程序組json

    二、模塊是一個文件,模塊文件名一般以.py結尾dom

  做用:ide

    一、讓一些相關數據,函數,類等有邏輯的組織在一塊兒,使邏輯結構更加清晰模塊化

    二、模塊中的數據,函數和類等可提供給其它模塊或程序使用函數

  模塊的分類:(同一個模塊在不一樣的操做系統下可能數不一樣類型的模塊)ui

    一、內置模塊(builtins),通常是用C語言來寫的,在解析器的內部能夠直接使用。模塊說明中有builtins關鍵字this

    二、標準庫模塊,安裝python時已經安裝且可直接使用。spa

    三、第三方模塊(一般爲開源),須要本身安裝

    四、用戶本身完成的模塊(能夠做爲其餘人的第三方模塊)

模塊的導入語句

  import語句

    語法:import 模塊名1 [as 模塊新名1][,模塊名2[ as 模塊新名2]],....

    做用:將某模塊總體導入到當前模塊

    用法:模塊.屬性名

  dir(obj)函數返回模塊全部屬性的字符串列表

  help(obj)能夠查看模塊相關的文檔字符串

  from  import語句

    語法: from 模塊名 import 模塊屬性名1[as 屬性新名1] [,模塊屬性名2[as 屬性新名2],....]

    做用:將模塊內的一個或多個屬性導入到當前模塊的做用域 

    說明:屬性是模塊內的全部全局變量

  from import * 語句 (通常不用)

    語法:from 模塊名 import *

    做用:將某模塊的全部屬性都導入到當前模塊

dir函數:

  dir([對象])返回一個字符串列表

  做用:一、若是沒有參數調用,則返回當前做用域內的全部變量的列表

     二、若是給定一個對象做爲參數,則返回這個對象的全部變量的列表

      1)對於一個模塊,返回這個模塊的所有屬性

      2)對於一個類對象,返回這個類對象的全部變量,親遞歸基類對象的全部變量

      3)對於其它對象,返回全部的變量,類變量,基類變量

數學模塊 math

  變量:

    math.e  天然對數的底e

    math.pi  圓周率pi

  函數:

    math.ceil(x)          對x向上取整,好比x = 1.2 ,返回2

    math.floor(x)           對x向下取整,好比x = 1.8 ,返回1

    math.sqrt(x)          返回x的平方根

    math.factorial(x)        求x的階乘

    math.log(x,[base])        返回以base爲底的x的對數,若是不給base,則以天然對數e爲底

    math.log10(x)          求以10爲底x的對數

    math.pow(x,y)             返回x**y

    math.fabs(x)          返回浮點數x的絕對值,好比x = -1,返回1.0

  角度degrees和弧度radians互換

    math.degrees(x)          將弧度x轉換爲角度

    math.radians(x)         將角度x轉換爲弧度

  三角函數,下面的x都是以弧度爲單位的

    math.sin(x)           返回x的正弦

    math.cos(x)             返回x的餘弦

    math.tan(x)           返回x的正切

    math.asin(x)            返回x的反正弦(返回值爲弧度)

    math.acos(x)           返回x的反餘弦(返回值爲弧度)

    math.atan(x)            返回x的反正切(返回值爲弧度)

時間模塊 time

此模塊提供了時間相關的函數,且一直可用

  時間簡介

    一、公元紀年是從公元0000年1月1日0時開始的

    二、計算機元年是從1970年1月1日0時開始的,此時間爲0,以後每過一秒時間+1

    三、UTC時間(Coordinated Universal Time )是從Greenwich時間開始計算的,UTC時間不會因時區問題而產生錯誤

    四、DST陽光節約時間(Daylight Saving Time ),又稱夏玲時,是一個通過日照時間修正後的時間(中國已經不用了)

  時間元組

    時間元組是一個9個整型元素組成的,這九個元素自前至後一次爲

      一、四位的年(如:1992)

      二、月(1-12)

      三、日(1-31)

      四、時(0-23)

      五、分(0-59)

      六、秒(0-59)

      七、星期幾(0-6,週一是0)

      八、元旦開始日(1-366)

      九、夏令時修時間(-1,0 or 1),對中國來講是0

    注:若是年份小於100,則會自動轉換爲加上1900後的值

  變量

    time.altzone    夏令時時間與UTC時間差(秒爲單位),-32400秒

    time.daylight      夏令時校訂時間,在中國爲0

    time.timezone   本地區時間與UTC時間差(秒爲單位),-28800秒

    time.tzname    時區名字的元組,第一個名字爲未經夏令時修正的時區,第二個名字爲經夏令時修正後的時間("CST","CST")

    注:CST爲中國標準時間(China Standard Time UTC+8:00)

  函數:

    time.time()     返回從計算機元年至當前時間的秒數的浮點數(UTC時間爲準)

    time.sleep(secs)    讓程序按給定秒數的浮點數睡眠一段時間

    time.gmtime([secs]) 用給定秒數轉換爲用UTC表達的時間元組(默認返回當前時間元組)

    time.asctime([tuple]) 將時間元組轉爲日期時間字符串,默認爲當前時間

    time.ctime([secs])  將時間戳轉發爲日期時間字符串,默認是當前時間

    time.mktime(tuple)    將本地日期時間元組轉爲新紀元秒數時間(UTC爲準)

    time.localtime([secs])   將UTC秒數時間轉爲日期元組(以本地時間爲準),默認爲當前時間

    注:time.mktime(time.localtime()) - time.mktime(time.gmtime()) = 28800.0 說明當時時間比UTC時間早8個小時

    time.clock()     返回處理器時間,3.0版本開始已經廢棄,改爲time.process_time()

    time.strftime(formt[,tuple]) 返回可讀字符串時間,格式有參數format決定。

    time.strptime()

    time.tzset()

  python中時間日期格式化符號

    %y      表示兩位數的年份(00-99)

    %Y      表示四位數的年份(0000-9999)

    %m      月份(01-12)

    %d      月內中的一天(0-31)

    %H      24小時制小時數(0-23)

    %I       12小時制小時數(01-12)

    %M      分鐘數(00-59)

    %S      秒數(00-59)

    %a      本地簡化星期名稱

    %A      本地完整星期名稱

    %b      本地簡化月份名稱

    %B      本地完整月份名稱

    %c      本地相應的的日期表示和時間表示

    %j       年內的一天(001-366)

    %p      本地A.M.或P.M.的等價符

    %U      一年中的星期數(00-53)星期日爲星期的開始

    %w      星期(0-6),星期天爲星期的開始

    %W      一年中的星期數(00-53)星期一爲星期的開始

    %x      本地相應的日期表示

    %X      本地相應的時間表示

    %Z      當前時區的名稱

    %%      %號自己

import time
print(time.localtime())#time.struct_time(tm_year=2018, tm_mon=7, tm_mday=19, tm_hour=0, tm_min=44, tm_sec=5, tm_wday=3, tm_yday=200, tm_isdst=0)
print(time.strftime("%Y-%m-%d  %H:%M:%S",time.localtime()))#2018-07-19  00:44:05
print(time.strftime("%y-%m-%d  %I:%M:%S",time.localtime()))#18-07-19  12:44:05
print(time.strftime("%a-%A-%b-%B-%c-%j-%p-%U-%w-%W-%x-%X-%Z-%%",time.localtime()))
#              Thu-Thursday-Jul-July-Thu Jul 19 00:44:05 2018-200-AM-28-4-29-07/19/18-00:44:05-?D1¨²¡À¨º¡Á?¨º¡À??-%
#               a    A       b   B             c               j   p  U w W     x        X         Z                 %

 

系統模塊sys

此模塊所有是運行時系統相關的信息

  做用:用於獲取和設置與系統相關的信息

  變量

    sys.path      返回模塊的搜索路徑,path[0]是當前腳本程序的路徑,初始化時使用pythonPath環境變量的值

    sys.modules    返回已加載模塊的字典,字典的鍵爲模塊名,值爲已加載的模塊

    sys.version      返回python版本信息的字符串:'3.5.4 (v3.5.4:3f56838, Aug  8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)]'

    sys.version_info   返回python版本信息的命名元組:sys.version_info(major=3, minor=5, micro=4, releaselevel='final', serial=0)

    sys.platform    操做系統平臺的名稱信息(Win32)

    sys.argv        命令行參數argv[0]表明當前腳本程序的路徑名,綁定用戶啓動程序時命令參數的列表

    sys.copyright    得到python版權相關信息

    sys.builtin_module_names  得到python內建模塊的名稱(字符串元組)

    標準輸入輸出時會用到

    sys.stdin      標準輸入文件對象,多用於input()

    sys.stdout       標準輸出文件對象,多用於print()

    sys.stderr        標準錯誤輸出文件對象,用於輸出錯誤信息

  函數:

    sys.exit([arg])    退出程序,正常退出時sys.exit(0)

    sys.getrecursionlimit()  獲得遞歸嵌套層次限制(棧的深度)

    sys.setrecursionlimit(n)  獲得和修改遞歸嵌套層次限制(棧的深度),你表明遞歸的次數,腳本中止,則這個限制還原

自定義模塊

  自定義模塊模塊名必須符合「標識符」的命名規則(同變量名),模塊有各自獨立的做用域

  模塊化編程的優勢:

    一、有利於多人合做開發

    二、使代碼更易於維護

    三、提升代碼的複用率

    四、有利於解決變量名衝突問題

import 語句  搜索模塊的路徑順序

  一、搜索程序運行時的路徑(當前路徑)

  二、sys.path提供的路徑

  三、搜索內置模塊

  說明:sys.path是一個存儲模塊搜索路徑的列表

      一、能夠把自定義的模塊放在相應的路徑下能夠導入

      二、能夠把本身模塊的路徑添加在sys.path列表中

模塊的加載過程:

  一、在模塊導入時,模塊的全部語句會執行

  二、若是一個模塊已經導入,則再次導入時不會從新執行模塊內的語句

模塊的從新加載:

  當已經被導入的模塊內容被修改後,能夠經過從新執行當前的程序從新加載,或者經過import imp;imp.reload(模塊名)的方法從新加載

模塊被導入和執行的過程

  一、先搜索相關的路徑找到模塊(.py)

  二、判斷是否有此模塊對應的.pyc文件,若是存在pyc文件且比.py文件新,則直接加載.pyc文件

  三、不然用.py文件生成.pyc文件後再進行加載

pyc 模塊的編譯文件:

  mymod1.py----編譯(compile)------→mymod1.pyc------解釋執行-----→python3

模塊的屬性

  屬性的實質是變量(是模塊內的全局變量)

模塊內預置的屬性

  __doc__屬性

    做用:用來綁定模塊的文檔字符串

  模塊內第一個沒有賦值給任何變量的字符串爲模塊的文檔字符串,(若是沒有賦值的字符串出如今第二個語句,則文檔字符串爲空)

  __file__屬性

    用來綁定模塊對應的文檔路徑名

      一、對於內建模塊,不綁定路徑(沒有__file__屬性)

      二、對於其它模塊,綁定路徑名的字符串(相對路徑:模塊名.py)

  __name__屬性

    此屬性用來記錄模塊的自身名字

    做用:一、記錄模塊名

       二、用來判斷是否爲主模塊(最早運行的模塊)

    說明:一、當此模塊爲主模塊時,__name__綁定"__main__"

       二、當此模塊不是主模塊時,此屬性綁定模塊名

模塊的__all__列表(不屬於模塊的屬性)

  模塊中的__all__列表是一個用來存放可導出屬性的字符串列表

  做用:當用from import * 語句導入時,只導入__all__列表內的屬性,若是沒有次列表則模塊的全部屬性都被導入

     不會影響import 模塊名 和  from 模塊名 import 屬性名 兩個語句的導入

模塊的隱藏屬性:

  模塊中以"_"下劃線(不只僅是單下劃線,多個下劃線)開頭的屬性,在from import *語句導入時,將不被導入,一般稱這些屬性爲隱藏屬性。

  若是該屬性被放入__all__列表中,將會被導入

隨機模塊 random

做用:用於模擬或生成隨機輸出的模塊

  函數(import random as R)

  R.random()            返回一個[0,1)之間的隨機實數

  R.randint(a,b)           返回一個 [a~b]之間的隨機整數,包括a,b

  R.uniform(a,b)            返回[a,b)區間內的隨機實數

  R.randrange([start,] stop[,step])   返回range(start,stop,step)中的隨機數

  R.choice(seq)           從序列中返回隨機數

  R.shuffle(seq, [,random])      隨機指定序列的順序(亂序序列),函數的第二個參數表明必須傳入random模塊中無參的函數目前只有random函數,可使用         R.random代替,目前版本沒有什麼用

  R.sample(seq,n)            從序列中選擇n個隨機且不重複的元素

import random
L = [i for i in range(10)]
L5 = random.sample(L,5)
print(L)
print(L5)

json&pick模塊

序列化:

  咱們把對象(變量)從內存中變成可存儲的或傳輸的過程稱之爲序列化,反過來,把變量內容從序列化後的對象從新讀到內存中稱爲反序列化

  說明:json不能講高級的對象序列化,好比:函數、類,若是要序列化函數 或者 類時須要使用pickle模塊

  json中的函數:

    一、dumps():序列化

    二、loades():反序列化

import json
dic = {'name':"xdl",'age':25}
#將字典對象序列,使之變爲可存儲的對象
dic = json.dumps(dic)
f = open('json_test','w')
f.write(dic)
import json
f = open('json_test','r')
dic = f.read()
#將讀出的數據反序列化,並讀入到內存中
dic = json.loads(dic)
print(dic['name'])

  pickle中的函數

    一、dumps():序列化對象

    二、loads():反序列化對象

import pickle
def foo():
    print('ok')
#將字典對象序列,使之變爲可存儲的對象,是字節串,須要使用wb寫入
foo = pickle.dumps(foo)
f = open('json_test','wb')
f.write(foo)
f.close()
import pickle
def foo():
    print('ok')
f = open('json_test','rb')
data = f.read()
#將讀出的數據反序列化,並讀入到內存中
#反序列化以前要建立一個與讀取的函數名相同的函數
#不然會報錯:AttributeError: Can't get attribute 'foo' on <module '__main__' from '
# /home/tarena/PycharmProjects/xdl/module/pickle_load.py'>
data = pickle.loads(data)
data()

logging模塊(日誌模塊)

使用步驟:

  一、獲取logger實例對象,若是參數爲空則返回root logger,

    logger = logging.getLogger()

  二、指定logger的格式

    formatter = logging.Formatter('自定義格式')

  三、建立具體的日誌handler,並將日誌格式添加處處理器上,包括文件日誌和終端日誌

    1)文件日誌:

      file_handler = logging.FileHandler('文件名稱.log')

      file_handler.setFormatter(formatter)

    2)終端日誌(在終端上顯示日誌信息)

      console_handler = logging.StreamHandler(sys.stdout)

      console_handler.setFormatter(formatter)

  四、設置日誌級別

    logger.setLevel(日誌級別)

  五、把日誌的handler對象添加到日誌對象logger中

    logger.addHandler(file_handler)

    logger.addHandler(console_handler)

  六、寫日誌   

    logger.debug('this is debug info')
    logger.info('this is information')
    logger.warn('this is warning message')
    logger.error('this is error message')
    logger.fatal('this is fatal message, it is same as logger.critical')
    logger.critical('this is critical message')

  七、移除日誌處理器

    logger.removeHandler(file_handler)
    logger.removeHandler(console_handler)

import logging
import sys
#一、獲取logger的實例,<Logger testlog (INFO)>,(INFO)是本身設置的日誌級別,若是不給參數,<RootLogger root (INFO)>
logger = logging.getLogger('testlog')
#二、指定logger的格式
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
#三、建立具體的日誌handler,文件日誌,終端日誌
#3.一、文件日誌
file_handler = logging.FileHandler('testLog.log')
file_handler.setFormatter(formatter)
#3.二、終端日誌
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(formatter)
#四、設置日誌的級別,高於等於這個默認級別纔會被顯示
logger.setLevel(logging.INFO)
#五、把日誌的handler添加到logger實例中
logger.addHandler(file_handler)
logger.addHandler(console_handler)
#六、寫日誌
logger.error("Test Error log")
logger.info("Test info log")
logger.debug("Test debug log")
#七、清空日誌
logger.removeHandler(file_handler)
logger.removeHandler(console_handler)

將日誌封裝成一個模塊

class LogerHelper:
    
    def __init__(self,name='LogerHelper',setLevel=logging.DEBUG):
        self.logger = logging.getLogger(name)
        self.formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s")
        self.file_handler = logging.FileHandler(name+'.log')
        self.file_handler.setFormatter(self.formatter)
        self.console_handler = logging.StreamHandler(sys.stdout)
        self.console_handler.setFormatter(self.formatter)
        self.logger.setLevel(setLevel)
        self.logger.addHandler(self.file_handler)
        self.logger.addHandler(self.console_handler)
        
    def writeLog(self,info,level='debug'):
        if level == 'critial':
            self.logger.critical(info)
        elif level == 'error':
            self.logger.error(info)
        elif level == 'warn':
            self.logger.warn(info)
        elif level == 'info':
            self.logger.info(info)
        elif level == 'debug':
            self.logger.debug(info)

    def removeLog(self):
        self.logger.removeHandler(self.file_handler)
        self.logger.removeHandler(self.console_handler)
        
if __name__ == '__main__':
    logger = LogerHelper()
    logger.writeLog("hello world",'critial')
    logger.writeLog("hello world",'error')
    logger.writeLog("hello world",'warn')
    logger.writeLog("hello world",'info')
    logger.writeLog("hello world",'debug')
    logger.removeLog()

 

包(模塊包)package

  包是將模塊以文件夾的組織形式進行分組管理的方法(包比其它普通文件夾多一個__init__.py)

  做用:將一系列模塊進行分類管理,有利於防止命名衝突,能夠在須要時加載一個或一部分模塊而不是所有模塊

  __init__.py文件

    常規包內必須存在的文件

    __init__.py會在包加載時被自動調用

    做用:一、編寫此包的內容

       二、在內部填寫文檔字符串

       三、在__init__.py內能夠加載此包所依賴的一些其它模塊

  包的導入

    用三條import語句能夠導入包(同模塊的導入規則)

    import 包名 [as 包別名]

    import 包名.模塊名 [as 模塊新名]

    import 包名.子包名.模塊名

 

    from 包名 import 模塊名  [as 模塊新名]

    from 包名.子包名 import 模塊名 [as 模塊新名]

    from 包名.子包名.模塊名 import 屬性名 [as  屬性新名]

 

    from 包名 import *

    from 包名.模塊名 import *

  包的__init__.py內的__all__列表

    做用:用來記錄此包中有哪些子包或模塊在用from 包 import * 語句導入時是否被導入

    說明:__all__列表只對from import * 語句起做用,若是沒有此列表則,都不會被導入

包的相對導入

  包的相對導入是指包內模塊的相互導入

  語法:一、from 相對路徑包或模塊 import 屬性或模塊名

     二、from 相對路徑或模塊 import *

  相對路徑:

     一、.表明當前目錄 如:a/b/c.py   其中.c.py表明b路徑

     二、..表明上一級目錄

     三、...表明上二級目錄

     四、....依次類推

     注:相對導入時不能超出包的外部,若是超出包的外部會報錯ValueError: attempted relative import beyond top-level package

包的加載路徑:

  和模塊的加載路徑相同

     一、當前文件夾

     二、sys.path給出的路徑

異常 exception

什麼是錯誤:

  錯誤是指因爲邏輯或語法等致使一個程序沒法正常執行的問題

  特色:有些錯誤是沒法預知的

什麼是異常:

  異常是程序出錯時標識的一種狀態,

  當異常發生時,程序不會再向下執行,而轉去調用此函數的地方待處理錯誤並恢復爲正常狀態

  做用:

    一、通知上層調用者有錯誤產生須要處理

    二、用做信號通知

try 語句的兩種語法

  try - except  語句

    語法:try:

          可能觸發異常的語句

       except 錯誤類型1 [as 變量1]:

          異常處理語句1

       except 錯誤類型2 [as 變量2]:

          異常處理語句2

       except(錯誤類型3,錯誤類型4,...)[as 變量3]:#前面必須是異常類型元組

          異常處理語句3

       ...

       except:                  #捕獲全部錯誤類型

          異常處理語句other

       else:

          未發生異常時執行的語句,(try語句嵌套的try語句出現異常並被處理,也要執行,若是沒有被處理將交給外部try語句進行處理)

       finally:

          最終執行語句(無論有沒有發生異常都會執行該語句,發生異常沒有被處理一樣會執行該語句)

    做用:嘗試捕獲異常,將程序轉爲正常狀態並繼續執行

    說明:一、as 子句用於綁定錯誤對象的變量,能夠省略不寫

       二、except子句能夠有一個或多個,但至少要有一個

       三、else子句最多隻能有一個,也能夠省略不寫

       四、finally子句最多隻能有一個,也能夠省略不寫

  try-finally語句

    語法:try:

        可能觸發異常的語句

       finally:

        最終語句

    說明:一、finally子句不能夠省略

       二、必定不存在except子句

    做用:一般try-finally語句來作觸發異常時必需要處理的事情,不管異常是否發生,finally子句都會執行

    注:try-finally語句不會改變程序的(正常/異常)狀態

raise語句

  做用:觸發一個錯誤,讓程序進入異常狀態

  語法:一、raise 異常類型 :raise ZeroDivisionError

     二、raise 異常對象:rasie ZeroDivisionError("被零除了...")

assert 語句(斷言語句)

  語法:assert 真值表達式,錯誤數據(一般是字符串)

  做用:當真值表達式爲False時,用錯誤數據建立一個AssertionError類型的錯誤,並進入異常狀態

  相似於:if   真值表達式 == False:

        raise AssertionError(錯誤數據)

                  

              

小結:

  接收錯誤消息:try- except

  作必需要處理的事情的語句:try-finally

  發錯誤消息的語句:一、raise 語句

           二、assert 語句

爲何要用異常處理處理機制:

  在程序調用層數較深時,向主調用函數傳遞錯誤信息須要用return語句層層傳遞比較麻煩,因此用異常處理機制

異常(高級)
    回顧異常相關的語句:
        try-exept         用來捕獲異常通知
        try-finally        用來作必定要作的事情
        raise               用來發生異常通知
        assert             用來根據條件來發出AssertionError類型的異常通知
    with語句:
        語法:with 表達式1 [as 變量1],表達式2 [as 變量2]:
                        語句塊
        做用:使用於對資源進行訪問的場合,肯定使用過程當中不論是否發生異常,都會執行必須的‘清理’操做,並釋放資源
            如:文件使用後自動關閉,線程中鎖的自動獲取和釋放等
        說明:可以用於with語句進行管理的對象必須是環境管理器

'''此示例示意用try-except 和 try-finally 組合來對文件進行操做'''
def read_from_file(filename="info.txt"):
    try:
        f = open(filename)
        try:
            print("正在讀取文件")
            n = int(f.read())
            print("n=",n)
        finally:
            f.close()
            print("文件已經關閉")
    except OSError:
        print("文件打開失敗")
read_from_file()
View Code

環境管理器:
    一、類內有__enter__ 和 __exit__實例方法的類被稱爲環境管理器
    二、能用with語句管理的對象必須是環境管理器
    三、__enter__方法將在進入with語句時被調用,並返回由as變量管理的對象
    四、__exit__方法將在離開with語句時被調用,且能夠用參數來判斷在離開with語句時是否有異常發生並作出相應的處理

contextlib,給咱們提供了一個裝飾器,只要按照它的代碼協議來實現函數內容,就能夠將這個函數對象變成一個上下文管理器

使用環境管理器(上下文管理器)的好處

  1.提升代碼的複用率

  2.提升代碼的優雅度

  3.提升代碼的可讀性

import contextlib

@contextlib.contextmanager
def open_func(file_name):
    #__enter__方法
    print('openfile',file_name,'in __enter__')
    file_handler = open(file_name,'r')

    #在被裝飾的函數中,必須是一個生成器,而yield以前的代碼至關於__enter__,以後的代碼至關於__exit__
    try:
        yield file_handler
    except Exception as e:
        print(e)
    finally:
        print('closefile',file_name,'in __exit__')
        file_handler.close()

if __name__ == "__main__":
    with open_func('aa.txt') as f:
        print(f)
        1 / 0
def read_from_file(filename="info.txt"):
    try:
        with open(filename) as f:
            print("正在讀取文件")
            n = int(f.read())
            print("n=",n)
            print("文件已經關閉")
    except OSError:
        print("文件打開失敗")
read_from_file()
View Code
'''此示例示意環境管理器的定義及使用'''
class A:
    def __enter__(self):
        print("已經進入with語句")
        return self #返回的對象將由as 綁定
    def __exit__(self,exc_type,exc_val,exc_tb):
        '''此方法會在退出with語句時自動調用
            exc_type在沒有異常時爲None,在出現異常時爲綁定異常類型
            exc_val在沒有異常時爲None,在出現異常時綁定錯誤對象
            exc_tb在沒有異常時爲None,在出現異常時綁定traceback(跟蹤)'''
        if exc_type is None:
            print("正常離開with語句!")
        else:
            print("異常離開with語句!")
            print("異常類型是:",exc_type)
            print("錯誤對象是",exc_val)
            print("traceback是:",exc_tb)
with A() as a:
    print("我是with語句內的一條語句")
    int(input("輸入一個數:"))
# 已經進入with語句
# 我是with語句內的一條語句
# 輸入一個數:aa
# 異常離開with語句!
# 異常類型是: <class 'ValueError'>
# 錯誤對象是 invalid literal for int() with base 10: 'aa'
# traceback是: <traceback object at 0x7f443a0e2748>
# Traceback (most recent call last):
#   File "02_enter_exit.py", line 24, in <module>
#     int(input("輸入一個數:"))
# ValueError: invalid literal for int() with base 10: 'aa'
View Code
相關文章
相關標籤/搜索