1. 程式人生 > >元類,異常處理

元類,異常處理

屬性 名稱 __new__ 語法 pri 萬能 行處理 n) 了解

什麽是元類:
# 源自一句話:在python中,一切皆對象,而對象都是由類實例化得到的。
# 內置的元類是type。
#
# 1. 調用元類---->自定義的類
# 2. 調用自定義的類---->自定義的對象

自定義類:
# class關鍵字創建自定義類的底層的工作原理,分為四步 例如:class OldboyTeacher(object,):
# 1. 先拿到類名:‘OldboyTeacher‘
# 2. 再拿到類的基類們:(object,)
# 3. 然後拿到類的名稱空間???(執行類體代碼,將產生的名字放到類的名稱空間也就是一個字典裏,補充exec)
# exec(‘str‘,{全局空間},{局部空間})
# 4. 調用元類實例化得到自定義的類: OldboyTeacher=type(‘OldboyTeacher‘,(object,),{...})
即: 自定義類的三個關鍵組成部分:
# 1. 類名
# 2. 類的基類們
# 3. 類的名稱空間
例如:
# 不依賴class關鍵字創建一個自定義類
class_name=‘OldboyTeacher‘
class_bases=(object,)
class_dic={}
# class_body="""
# school = ‘Oldboy‘
#
# def __init__(self,name,age,sex):
# self.name=name
# self.age=age
# self.sex=sex
#
# def score(self):
# print(‘%s is scoring‘ %self.name)
# """
# exec(class_body,{},class_dic)
# print(class_dic)
OldboyTeacher=type(class_name,class_bases,class_dic)
*************************************有點問題*********************************************
實例
class Mymeta(type): #但凡繼承了type的類才能稱之為自定義的元類,否則就是只是一個普通的類
def __init__(self,class_name,class_bases,class_dic):
pass
# class OldboyTeacher(object,metaclass=Mymeta): #OldboyTeacher=Mymeta(‘OldboyTeacher‘,(object,),{...})
# school = ‘Oldboy‘
#
# def __init__(self,name,age,sex):
# self.name=name
# self.age=age
# self.sex=sex
#
# def score(self):
# print(‘%s is scoring‘ %self.name)


正真意義上的自定義生成類(加邏輯加標準++++++等等):
控類的產生
# 1.類名必須用駝峰體
# 2.類體必須有文檔註釋,且文檔註釋不能為空
# 3................................
class Mymeta(type):
def __init__(self,class_name,class_bases,class_dic):
if class_name.islower():
raise TypeError(‘類名必須使用駝峰體‘)

doc=class_dic.get(‘__doc__‘)
if doc is None or len(doc) == 0 or len(doc.strip(‘\n ‘)) == 0:
raise TypeError(‘類體中必須有文檔註釋,且文檔註釋不能為空‘)

class OldboyTeacher(object,metaclass=Mymeta):
pass

自定義類的調用(生成類的實例):
#總結:對象之所以可以調用,是因為對象的類中有一個函數__call__
#推導:如果一切皆對象,那麽OldboyTeacher也是一個對象,該對象之所可以調用,肯定是這個對象的類中也定義了一個函數__call__
‘‘‘
class Mymeta(type): #但凡繼承了type的類才能稱之為自定義的元類,否則就是只是一個普通的類
def __call__(self, *args, **kwargs): #self=OldboyTeacher這個類,args=(‘egon‘,18,‘male‘),kwargs={}
# 1. 先產生一個空對象
tea_obj=self.__new__(self) #tea_obj是OldboyTeacher這個類的對象
# 2. 執行__init__方法,完成對象的初始屬性操作
self.__init__(tea_obj,*args,**kwargs)
# 3. 返回初始化好的那個對象
return tea_obj
‘‘‘

正真意義上的自定義類的調用(加邏輯加標準++++++等等):
class Mymeta(type):
def __call__(self, *args, **kwargs):

tea_obj=self.__new__(self)
self.__init__(tea_obj,*args,**kwargs)
tea_obj.__dict__={(‘_%s__%s‘ %(self.__name__,k)):v for k,v in tea_obj.__dict__.items()}

return tea_obj


自定義類的屬性查找順序:
1.mro(最後還有個object)
2.type/[自定義元類(type)]

1. 什麽是異常處理
異常是錯誤發生的信號,一旦程序出錯就會產生一個異常,如果該異常
沒有被應用程序處理,那麽該異常就會拋出來,程序的執行也隨之終止

異常包含三個部分:
1. traceback異常的追蹤信息
2. 異常的類型
3. 異常的信息

錯誤分為兩大類:
1. 語法上的錯誤:在程序運行前就應該立即修正
2. 邏輯上的錯誤
2. 為何要異常處理

避免程序因為異常而崩潰,所以在應用程序中應該對異常進行處理,從而增強程序的健壯性

3. 如何異常處理
try:
代碼1
代碼2
代碼3
......
except NameError:
當拋出的異常是NameError時執行的子代碼塊
except ....:
pass
except ...:
pass
else:
print(‘else必須放到後面,else的子代碼塊會在被檢測的代碼沒有異常的情況下執行‘)
finally:
print(‘無論被檢測的代碼有沒有異常都會執行‘)
f.close()
#
## 萬能異常類型Exception as e:可以匹配任意類型的異常
## except (nameerror,keyerror,indexerror...)as e:把要找的異常寫成一行
#


# 主動觸發異常
# print(‘===>1‘)
# print(‘===>2‘)
# raise TypeError(‘類型錯誤‘)
# print(‘===>3‘)
# 自定義異常類型(了解)
# class MyException(BaseException):
# def __init__(self,msg):
# super().__init__()
# self.msg=msg
#
# def __str__(self):
# return ‘<%s>‘ %self.msg
#
# raise MyException(‘我自定義的異常‘)


# 斷言(了解)
print(‘上半部分,生產數據‘)
l=[1,2,3,4]

# if len(l) != 5:
# raise TypeError(‘列表的長度必須為5‘)
assert len(l) == 5

print(‘下半部分,處理數據‘)

元類,異常處理