Python中new與裝飾器

課件:new方法、描述符、裝飾器

課件:new方法、描述符、裝飾器知識點一:__ new __1、單例模式(難點)知識點二:(閉包)裝飾器(重、難點)知識點三:內置裝飾器

知識點一:__ new __

__ new __ (cls[,...])的參數(shù),__ new __ 方法的第一個參數(shù)是這個類,而其余的參數(shù)會在調用成功后全部傳遞給 __ init __ 方法初始化。

所以, __ new __ 方法(第一個執(zhí)行)先于 __ init __ 方法執(zhí)行:

我們比較兩個方法的參數(shù),可以發(fā)現(xiàn)new方法是傳入類(cls),而init方法傳入類的實例化對象(self),而有意思的是,__ new __ 方法返回的值就是一個實例化對象(ps:如果new方法返回None,則init方法不會被執(zhí)行,并且返回值只能調用父類中的new方法,而不能調用毫無關系的類的new方法)。

classBase:

def__init__(self):

print('這是初始化方法里面')

def__new__(cls,*args,**kwargs):

print('這個cls是:',cls)# cls 就是Base類

print('這是在new方法里面')

returnobject.__new__(cls)# 必須有返回值

#實例的時候會先調用_new_方法,然后再調用初始化方法

test=Base()

1、單例模式(難點)

單例模式(Singleton Pattern)是一種常用的軟件設計模式,該模式的主要目的是確保某一個類只有一個實例存在。當你希望在整個系統(tǒng)中,某個類只能出現(xiàn)一個實例時,單例對象就能派上用場。

比如,某個服務器程序的配置信息存放在一個文件中,客戶端通過一個 AppConfig 的類來讀取配置文件的信息。如果在程序運行期間,有很多地方都需要使用配置文件的內容,也就是說,很多地方都需要創(chuàng)建 AppConfig 對象的實例,這就導致系統(tǒng)中存在多個 AppConfig 的實例對象,而這樣會嚴重浪費內存資源,尤其是在配置文件內容很多的情況下。事實上,類似 AppConfig 這樣的類,我們希望在程序運行期間只存在一個實例對象。

在 Python 中,我們可以用多種方法來實現(xiàn)單例模式

classPerson:

pass

xiaoming=Person()

xiaohong=Person()

print(id(xiaoming))

print(id(xiaohong))地址是不是都是不一樣的

# 單例模式要實現(xiàn)的效果就是--- 每一次實例化所創(chuàng)建的實例都是同一個,內存地址都是一樣的

classA:

_instance=None# 實例

def__new__(cls,*args,**kwargs):

ifcls._instance==None:

cls._instance=object.__new__(cls)

returncls._instance

else:

returncls._instance

a=A()

b=A()

print(id(a))

print(id(b))

----------------------------------

classPerson:

def__new__(cls,*args,**kwargs):# self 實例本身 ? cls 類本身

ifnothasattr(cls,'instance'):

cls.instance=super().__new__(cls)

returncls.instance


def__init__(self,name):

self.name=name

xiaoming=Person('小明')

laowang=Person('老王')

print(id(xiaoming))

print(id(laowang))

print(laowang.name)

print(xiaoming.name)

單例的運用:任務管理器? 回收站? 項目日志? 多線程的線程池的設計一般也是采用單例模式

知識點二:(閉包)裝飾器(重、難點)

# 裝飾器

# 閉包的應用

# 寫函數(shù)

defouter():

a=2

definner():

print(a)

returninner# 返回來的是函數(shù)體

概念:不改變原有函數(shù)的基礎上,給函數(shù)增加一些新的功能

deffunc():

print('__正在登陸__')# 登陸功能,不改變增加驗證功能

defmodify(func):

defwrapper():

result=func()

returnresult+',討厭'

returnwrapper

@modify

defgirl():

return'死鬼'

a=girl()

print(a)

知識點三:內置裝飾器

classRectangles:

name='bbbb'

def__init__(self,length,width):

self.length=length

self.width=width

defarea(self):

areas=self.length*self.width

returnareas

@property# 就像訪問屬性一樣? 調用可以不用括號

defareas(self):

returnself.width*self.length

@staticmethod# 靜態(tài)方法? 和class類斷開聯(lián)系? 不加self

deffunc():# self? 在調用的時候會報錯

print('staticmethod func')

@classmethod# 類方法 傳遞類本身? 直接類方法

defshow(cls):# cls 代表類本身

print(cls.name)

print('show fun')

a1=Rectangles(20,30)

print(a1.area())

print(a1.areas)# 裝飾器 property

Rectangles.func()# 不用實例化,不能使用類屬性和方法,類中的函數(shù)

Rectangles.show()# 不用實例化,可以使用類屬性和方法

類當做裝飾器必須使用 __ call __

classTest_Class:

def__init__(self,func):

self.func=func

def__call__(self,*args,**kwargs):

print('類----cal----')

returnself.func()

@Test_Class

deffun_test():

print('這是個測試函數(shù)')

fun_test()

作業(yè):代碼運行時間案例

importtime

defrun_time(func):

defnew_fun(*args,**kwargs):

t0=time.time()

back=func(*args,**kwargs)

print('函數(shù)運行的時間: %s'%(time.time()-t0))

returnback

returnnew_fun

@run_time

defaaa():

time.sleep(5)

aaa()

使用裝飾器計算下type()函數(shù)和isinstance()函數(shù)哪個函數(shù)執(zhí)行的速度更快

print(isinstance(100,int))

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容