建立類的時(shí)候,需要使用_init_魔法方法,感到好奇,查閱資料后,總結(jié)一下。
_new_(cls[,...])
當(dāng)對(duì)象創(chuàng)建時(shí),第一個(gè)調(diào)用的方法就是_new_,而前面說到的_init_方法更像是一個(gè)配置文件。_new_才是真正的構(gòu)造函數(shù),創(chuàng)建并返回一個(gè)實(shí)例對(duì)象,如果_new_只調(diào)用了一次,就會(huì)得到一個(gè)對(duì)象。它的第一個(gè)參數(shù)是這個(gè)類,其他的參數(shù)是用來直接傳遞給_init_ 方法。
- _new_ 是在一個(gè)對(duì)象實(shí)例化的時(shí)候所調(diào)用的第一個(gè)方法
- 它的第一個(gè)參數(shù)是這個(gè)類,其他的參數(shù)是用來直接傳遞給 _init_ 方法
- _new_ 決定是否要使用該 _init_ 方法,因?yàn)?_new_ 可以調(diào)用其他類的構(gòu)造方法或者直接返回別的實(shí)例對(duì)象來作為本類的實(shí)例,如果 _new_ 沒有返回實(shí)例對(duì)象,則 _init_ 不會(huì)被調(diào)用
- _new_ 主要是用于繼承一個(gè)不可變的類型比如一個(gè) tuple 或者 string
class TestClass:
def __init__(self):
print("調(diào)用__init__")
def __new__(cls, *args, **kwargs):
print("調(diào)用__new__")
return object.__new__(cls)#返回當(dāng)前類的實(shí)例
t = TestClass()
上下文管理器
可能有人好奇上下文管理器是什么,和魔法方法有啥關(guān)系?平時(shí)讀取文件的時(shí)候,常常說要使用with open()來進(jìn)行文件內(nèi)容的讀取,而with后跟著的就是上下文管理器,簡單的說,任何實(shí)現(xiàn)了_enter_方法和_exit_方法的對(duì)象都可以稱之為上下文管理器。它可以在執(zhí)行with 包裹的執(zhí)行代碼(也就是自己寫的那部分)前后執(zhí)行對(duì)應(yīng)的_enter_方法或_exit_方法,可以想到的就是open()執(zhí)行的_enter_是打開文件,而_exit_則是關(guān)閉了文件。順便說一句,python還提供了一個(gè)contextmanager的裝飾器,更進(jìn)一步簡化了上下文管理器的實(shí)現(xiàn)方式。
class TestClass:
def __init__(self,name):
self.name = name
def __enter__(self):
print("%s開始工作啦!"%self.name)
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type is None: # 可以利用exc_type來捕獲異常
print("%s結(jié)束工作啦!"%self.name)
else:
print("工作出錯(cuò)了!")
print('Type: ', exc_type)
print('Value:', exc_val)
print('TreacBack:', exc_tb)
# 返回值決定了捕獲的異常是否繼續(xù)向外拋出
# 如果是 False 那么就會(huì)繼續(xù)向外拋出,程序會(huì)看到系統(tǒng)提示的異常信息
# 如果是 True 不會(huì)向外拋出,程序看不到系統(tǒng)提示信息,只能看到else中的輸出
return True
t = TestClass(name = "卡比獸")
with t :
raise NameError
print:
卡比獸開始工作啦!
工作出錯(cuò)了!
('Type: ', <type 'exceptions.NameError'>)
('Value:', NameError())
('TreacBack:', <traceback object at 0x0000000003CF9348>)
待更新。。。
參考鏈接