欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

在Python中如何實現(xiàn)單例模式

本篇內(nèi)容主要講解“在Python中如何實現(xiàn)單例模式”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“在Python中如何實現(xiàn)單例模式”吧!

成都創(chuàng)新互聯(lián)是一家專注于成都做網(wǎng)站、網(wǎng)站設(shè)計與策劃設(shè)計,肇慶網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)十余年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:肇慶等地區(qū)。肇慶做網(wǎng)站價格咨詢:028-86922220

方法一:使用裝飾器實現(xiàn)單例模式。

from functools 
import wraps
def singleton(cls):
   """單例類裝飾器"""
   instances = {}

   @wraps(cls)
   def wrapper(*args, **kwargs):
       if cls not in instances:
           instances[cls] = cls(*args, **kwargs)
       return instances[cls]

   return wrapper @singleton
class President:
   pass

擴展:裝飾器是Python中非常有特色的語法,用一個函數(shù)去裝飾另一個函數(shù)或類,為其添加額外的能力。通常通過裝飾來實現(xiàn)的功能都屬橫切關(guān)注功能,也就是跟正常的業(yè)務(wù)邏輯沒有必然聯(lián)系,可以動態(tài)添加或移除的功能。裝飾器可以為代碼提供緩存、代理、上下文環(huán)境等服務(wù),它是對設(shè)計模式中代理模式的踐行。在寫裝飾器的時候,帶裝飾功能的函數(shù)(上面代碼中的wrapper函數(shù))通常都會用functools模塊中的wraps再加以裝飾,這個裝飾器最重要的作用是給被裝飾的類或函數(shù)動態(tài)添加一個__wrapped__屬性,這個屬性會將被裝飾之前的類或函數(shù)保留下來,這樣在我們不需要裝飾功能的時候,可以通過它來取消裝飾器,例如可以使用President = President.__wrapped__來取消對President類做的單例處理。需要提醒大家的是:上面的單例并不是線程安全的,如果要做到線程安全,需要對創(chuàng)建對象的代碼進(jìn)行加鎖的處理。在Python中可以使用threading模塊的RLock對象來提供鎖,可以使用鎖對象的acquire和release方法來實現(xiàn)加鎖和解鎖的操作。當(dāng)然,更為簡便的做法是使用鎖對象的with上下文語法來進(jìn)行隱式的加鎖和解鎖操作。

方法二:使用元類實現(xiàn)單例模式。

class SingletonMeta(type):
   """自定義單例元類"""

   def __init__(cls, *args, **kwargs):
       cls.__instance = None
       super().__init__(*args, **kwargs)

   def __call__(cls, *args, **kwargs):
       if cls.__instance is None:
           cls.__instance = super().__call__(*args, **kwargs)
       return cls.__instance class President(metaclass=SingletonMeta):
   pass

擴展:Python是面向?qū)ο蟮木幊陶Z言,在面向?qū)ο蟮氖澜缰校磺薪詾閷ο?。對象是通過類來創(chuàng)建的,而類本身也是對象,類這樣的對象是通過元類來創(chuàng)建的。我們在定義類時,如果沒有給一個類指定父類,那么默認(rèn)的父類是object,如果沒有給一個類指定元類,那么默認(rèn)的元類是type。通過自定義的元類,我們可以改變一個類默認(rèn)的行為,就如同上面的代碼中,我們通過元類的__call__魔術(shù)方法,改變了President類的構(gòu)造器那樣。

關(guān)于單例模式,在面試中還有可能被問到它的應(yīng)用場景。通常一個對象的狀態(tài)是被其他對象共享的,就可以將其設(shè)計為單例,例如項目中使用的數(shù)據(jù)庫連接池對象和配置對象通常都是單例,這樣才能保證所有地方獲取到的數(shù)據(jù)庫連接和配置信息是完全一致的;而且由于對象只有唯一的實例,因此從根本上避免了重復(fù)創(chuàng)建對象造成的時間和空間上的開銷,也避免了對資源的多重占用。再舉個例子,項目中的日志操作通常也會使用單例模式,這是因為共享的日志文件一直處于打開狀態(tài),只能有一個實例去操作它,否則在寫入日志的時候會產(chǎn)生混亂。

題目002:不使用中間變量,交換兩個變量a和b的值。

點評:典型的送人頭的題目,在其他編程語言中不使用中間變量交換兩個變量的值可以使用異或運算,Python中還可以通過內(nèi)置的字節(jié)碼指令直接交換兩個變量的值。

方法一:

a = a ^ b
b = a ^ b
a = a ^ b

方法二:

a, b = b, a

擴展:需要注意,a, b = b, a這種做法其實并不是元組解包,雖然很多人都這樣認(rèn)為。Python字節(jié)碼指令中有ROT_TWO指令來支持這個操作,類似的還有ROT_THREE,對于3個以上的元素,如a, b, c, d = b, c, d, a,才會用到創(chuàng)建元組和元組解包。想知道你的代碼對應(yīng)的字節(jié)碼指令,可以使用Python標(biāo)準(zhǔn)庫中dis模塊的dis函數(shù)來反匯編你的Python代碼。

題目003:寫一個刪除列表中重復(fù)元素的函數(shù),要求去重后元素相對位置保持不變。

點評:這個題目在初中級Python崗位面試的時候經(jīng)常出現(xiàn),題目源于《Python Cookbook》這本書第一章的第10個問題,有很多面試題其實都是這本書上的原題,所以建議大家有時間的話好好研讀一下這本書。

def 
dedup(items):
   no_dup_items = []
   seen = set()
   for item in items:
       if item not in seen:
           no_dup_items.append(item)
           seen.add(item)
   return no_dup_items

當(dāng)然,也可以像《Python Cookbook》書上的代碼那樣,把上面的函數(shù)改造成一個生成器。

def 
dedup(items):
   seen = set()
   for item in items:
       if item not in seen:
           yield item
           seen.add(item)

擴展:由于Python中的集合底層使用哈希存儲,所以集合的in和not in成員運算在性能上遠(yuǎn)遠(yuǎn)優(yōu)于列表,所以上面的代碼我們使用了集合來保存已經(jīng)出現(xiàn)過的元素。集合中的元素必須是hashable對象,因此上面的代碼在列表元素不是hashable對象時會失效,要解決這個問題可以給函數(shù)增加一個參數(shù),該參數(shù)可以設(shè)計為返回哈希碼或hashable對象的函數(shù)。

題目004:假設(shè)你使用的是官方的CPython,說出下面代碼的運行結(jié)果。

點評:下面的程序?qū)嶋H開發(fā)并沒有什么意義,但卻是CPython中的一個大坑,這道題旨在考察面試者對官方的Python解釋器到底了解到什么程度。

a, b, c, d = 
1, 
1, 
1000, 
1000
print(a is b, c is d)

def foo():
   e = 1000
   f = 1000
   print(e is f, e is d)
   g = 1
   print(g is a)

foo()

結(jié)果:

True False
True False
True

上面代碼中a is b的結(jié)果是True但c is d的結(jié)果是False,這一點的確讓人費解。這個結(jié)果是因為CPython出于性能優(yōu)化的考慮,把頻繁使用的整數(shù)對象用一個叫small_ints的對象池緩存起來造成的。small_ints緩存的整數(shù)值被設(shè)定為[-5, 256]這個區(qū)間,也就是說,如果使用CPython解釋器,在任何引用這些整數(shù)的地方,都不需要重新創(chuàng)建int對象,而是直接引用緩存池中的對象。如果整數(shù)不在該范圍內(nèi),那么即便兩個整數(shù)的值相同,它們也是不同的對象。

CPython底層為了進(jìn)一步提升性能還做了一個設(shè)定:對于同一個代碼塊中值不在small_ints緩存范圍之內(nèi)的整數(shù),如果同一個代碼塊中已經(jīng)存在一個值與其相同的整數(shù)對象,那么就直接引用該對象,否則創(chuàng)建新的int對象。需要大家注意的是,這條規(guī)則對數(shù)值型適用,但對字符串則需要考慮字符串的長度,這一點可以自行證明。

擴展:如果你用PyPy(另一種Python解釋器實現(xiàn),支持JIT,對CPython的缺點進(jìn)行了改良,在性能上優(yōu)于CPython,但對三方庫的支持略差)來運行上面的代碼,你會發(fā)現(xiàn)所有的輸出都是True。

題目005:Lambda函數(shù)是什么,舉例說明的它的應(yīng)用場景。

點評:這個題目主要想考察的是Lambda函數(shù)的應(yīng)用場景,潛臺詞是問你在項目中有沒有使用過Lambda函數(shù),具體在什么場景下會用到Lambda函數(shù),借此來判斷你寫代碼的能力。因為Lambda函數(shù)通常用在高階函數(shù)中,主要的作用是通過傳入或返回函數(shù)實現(xiàn)代碼的解耦合。

Lambda函數(shù)也叫匿名函數(shù),它功能簡單用一行代碼就能實現(xiàn)的小型函數(shù)。Python中的Lambda函數(shù)只能寫一個表達(dá)式,這個表達(dá)式的執(zhí)行結(jié)果就是函數(shù)的返回值,不用寫return關(guān)鍵字。Lambda函數(shù)因為沒有名字,所以也不會跟其他函數(shù)發(fā)生命名沖突的問題。

面試的時候有可能還會考你用Lambda函數(shù)來實現(xiàn)一些功能,也就是用一行代碼來實現(xiàn)題目要求的功能,例如:用一行代碼實現(xiàn)求階乘的函數(shù),用一行代碼實現(xiàn)求最大公約數(shù)的函數(shù)等。

fac = lambda x: __import__('functools').reduce(int.__mul__, range(1, x + 1), 1)
gcd = lambda x, y: y % x and gcd(y % x, x) or x

Lambda函數(shù)其實最為主要的用途是把一個函數(shù)傳入另一個高階函數(shù)(如Python內(nèi)置的filter、map等)中來為函數(shù)做解耦合,增強函數(shù)的靈活性和通用性。下面的例子通過使用filter和map函數(shù),實現(xiàn)了從列表中篩選出奇數(shù)并求平方構(gòu)成新列表的操作,因為用到了高階函數(shù),過濾和映射數(shù)據(jù)的規(guī)則都是函數(shù)的調(diào)用者通過另外一個函數(shù)傳入的,因此這filter和map函數(shù)沒有跟特定的過濾和映射數(shù)據(jù)的規(guī)則耦合在一起。

items = [12, 5, 7, 10, 8, 19]
items = list(map(lambda x: x ** 2, filter(lambda x: x % 2, items)))
print(items)    # [25, 49, 361]

當(dāng)然,用列表的生成式來實現(xiàn)上面的代碼更加簡單明了,如下所示。

items = [12, 5, 7, 10, 8, 19]
items = [x ** 2 for x in items if x % 2]
print(items)    # [25, 49, 361]

到此,相信大家對“在Python中如何實現(xiàn)單例模式”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

文章名稱:在Python中如何實現(xiàn)單例模式
網(wǎng)站URL:http://aaarwkj.com/article48/gpehep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站網(wǎng)站排名、定制網(wǎng)站網(wǎng)站改版、面包屑導(dǎo)航網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護公司
亚洲av乱码国产精品观看| 国产成人av中文字暮在线| 国产麻豆三级在线观看| 色综合av男人的天堂| 亚洲综合香蕉在线视频| 成人国产视频免费观看| 久久伊人这里都是精品| 麻豆一区二区人妻网站| 麻豆久久av免费观看| 日韩精品一区中文字幕在线| 亚洲国产成人精品福利| 少妇欧美日韩精品在线观看| 日韩三级视频一区二区 | 国产第一页国产第一页| 香蕉欧美在线视频播放| 日韩毛片免费看美日韩毛片| 色吊最新在线视频免费观看| 亚洲欧美一区二区色慰| 一区二区三区人妻av| 亚洲乱码精品一区二区| 成人免费亚洲av在线| 中文字幕乱码一区二区欧美| 亚洲精品aa片在线观看国产| 国产一区二区精品日韩| 在线看岛国毛片十八禁| 天堂av在线播放观看| 国产午夜草莓视频在线观看| 日本免费一区二区三个| 国产精品不卡一不卡二| 日本韩国一级黄色免费| 日日夜夜天天操天天干| 欧美一区二区三区情色| 综合资源网日韩天天操| 国产精品夜色一区二区三区不卡 | 夜夜操狠狠操天天摸| 亚洲黄色成人在线观看| 91人妻精品丰满少妇区| 亚洲欧美日韩精品区| 18禁的视频在线观看| 国产一区二区三区本色| 丝袜美腿诱惑国产在线|