<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          聊聊 Python 面試最常被問(wèn)到的幾種設(shè)計(jì)模式(上)

          共 6401字,需瀏覽 13分鐘

           ·

          2021-11-12 16:00



          1. 前言

          在很多人的印象里,Python 作為一款動(dòng)態(tài)編程語(yǔ)言,在日常開(kāi)發(fā)中也很少涉及到設(shè)計(jì)模式

          事實(shí)上,任何一個(gè)編程語(yǔ)言都可以使用設(shè)計(jì)模式,它可以保證代碼的規(guī)范性,只是每一種語(yǔ)言的實(shí)現(xiàn)方式略有不同而已

          今天我們聊聊 Python 面試中,常被問(wèn)到的 5 種設(shè)計(jì)模式,它們是:單例模式、工廠(chǎng)模式、構(gòu)建者模式、代理模式、觀察者模式

          2. 單例模式

          單例模式,是最簡(jiǎn)單常用的設(shè)計(jì)模式,主要目的是保證某一個(gè)實(shí)例對(duì)象只會(huì)存在一個(gè),減少資源的消耗

          Python 單例模式有很多實(shí)現(xiàn)方式,這里推薦下面 2 種

          第 1 種,重寫(xiě)?__new__ 方法

          定義一個(gè)實(shí)例變量,在?__new__ 方法中保證這個(gè)變量?jī)H僅初始化一次

          #?單例模式
          class?Singleton(object):
          ????_instance?=?None

          ????def?__new__(cls,?*args,?**kwargs):
          ????????if?cls._instance?is?None:
          ????????????cls._instance?=?object.__new__(cls,?*args,?**kwargs)
          ????????return?cls._instance

          使用方式如下:

          if?__name__?==?'__main__':
          ????#?構(gòu)建3個(gè)實(shí)例
          ????instance1?=?Singleton()
          ????instance2?=?Singleton()
          ????instance3?=?Singleton()

          ????#?打印出實(shí)例的內(nèi)存地址,判斷是否是同一個(gè)實(shí)例
          ????print(id(instance1))
          ????print(id(instance2))
          ????print(id(instance3))

          第 2 種,閉包定義裝飾器

          使用閉包的方式定義一個(gè)單例裝飾器,將類(lèi)的定義隱藏到閉包函數(shù)中

          def?singleton(cls):
          ????"""
          ????定義單例的裝飾器(閉包)
          ????:param?cls:
          ????:return:
          ????"""

          ????_instance?=?{}

          ????def?_singleton(*args,?**kargs):
          ????????if?cls?not?in?_instance:
          ????????????_instance[cls]?=?cls(*args,?**kargs)
          ????????return?_instance[cls]

          ????return?_singleton

          使用上面裝飾器的類(lèi),構(gòu)建的實(shí)例都能保證單例存在

          @singleton
          class?Singleton(object):
          ????"""單例實(shí)例"""

          ????def?__init__(self,?arg1):
          ????????self.arg1?=?arg1

          使用方式如下:

          if?__name__?==?'__main__':
          ????instance1?=?Singleton("xag")
          ????instance2?=?Singleton("xingag")

          ????print(id(instance1))
          ????print(id(instance2))

          需要注意的是,上面 2 種方式創(chuàng)建的單例并不適用于多線(xiàn)程

          要保證多線(xiàn)程中構(gòu)建的實(shí)例對(duì)象為單例,需要在?__new__ 函數(shù)中使用?threading.Lock()?加入同步鎖

          class?Singleton(object):
          ????"""
          ????實(shí)例化一個(gè)對(duì)象
          ????"""


          ?????#?鎖
          ????_instance_lock?=?threading.Lock()

          ????def?__init__(self):
          ????????pass

          ????def?__new__(cls,?*args,?**kwargs):
          ????????if?not?hasattr(Singleton,?"_instance"):
          ????????????with?Singleton._instance_lock:
          ????????????????if?not?hasattr(Singleton,?"_instance"):
          ????????????????????Singleton._instance?=?object.__new__(cls)
          ????????return?Singleton._instance

          使用的時(shí)候,在線(xiàn)程任務(wù)中實(shí)例化對(duì)象,運(yùn)行線(xiàn)程即可

          def?task(arg):
          ????"""
          ????任務(wù)
          ????:param?arg:
          ????:return:
          ????"""

          ????instance?=?Singleton()
          ????print(id(instance),?'\n')

          if?__name__?==?'__main__':
          ????#?3個(gè)線(xiàn)程
          ????for?i?in?range(3):
          ????????t?=?threading.Thread(target=task,?args=[i,?])
          ????????t.start()

          這樣,就保證了多線(xiàn)程創(chuàng)建的實(shí)例是單例存在的,不會(huì)導(dǎo)致臟數(shù)據(jù)!

          3. 工廠(chǎng)模式

          生產(chǎn)3種水果對(duì)象為例,定義 3 類(lèi)水果,分別是:蘋(píng)果、香蕉、橘
          #?定義一系列水果
          class?Apple(object):
          ????"""蘋(píng)果"""

          ????def?__repr__(self):
          ????????return?"蘋(píng)果"


          class?Banana(object):
          ????"""香蕉"""

          ????def?__repr__(self):
          ????????return?"香蕉"


          class?Orange(object):
          ????"""橘子"""

          ????def?__repr__(self):
          ????????return?"橘子"
          工廠(chǎng)模式包含:簡(jiǎn)單工廠(chǎng)、工廠(chǎng)方法、抽象工廠(chǎng)
          第 1 種,簡(jiǎn)單工廠(chǎng)
          簡(jiǎn)單工廠(chǎng)是最常見(jiàn)的工廠(chǎng)模式,適用于簡(jiǎn)單的業(yè)務(wù)場(chǎng)景
          首先,定義一個(gè)工廠(chǎng)類(lèi),創(chuàng)建一個(gè)靜態(tài)方法,根據(jù)輸入的類(lèi)型,返回不同的對(duì)象
          class?FactorySimple(object):
          ????"""簡(jiǎn)單工廠(chǎng)模式"""

          ????@staticmethod
          ????def?get_fruit(fruit_name):
          ????????if?'a'?==?fruit_name:
          ????????????return?Apple()
          ????????elif?'b'?==?fruit_name:
          ????????????return?Banana()
          ????????elif?'o'?==?fruit_name:
          ????????????return?Orange()
          ????????else:
          ????????????return?'沒(méi)有這種水果'
          使用方式如下:
          if?__name__?==?'__main__':
          ????#?分別獲取3種水果
          ????#?輸入?yún)?shù),通過(guò)簡(jiǎn)單工廠(chǎng),返回對(duì)應(yīng)的實(shí)例
          ????instance_apple?=?FactorySimple.get_fruit('a')
          ????instance_banana?=?FactorySimple.get_fruit('b')
          ????instance_orange?=?FactorySimple.get_fruit('o')
          第 2 種,工廠(chǎng)方法
          工廠(chǎng)方法將創(chuàng)建對(duì)象的工作讓相應(yīng)的工廠(chǎng)子類(lèi)去實(shí)現(xiàn),保證在新增工廠(chǎng)類(lèi)時(shí),不用修改原有代碼
          首先,創(chuàng)建一個(gè)抽象公共工廠(chǎng)類(lèi),并定義一個(gè)生產(chǎn)對(duì)象的方法
          import?abc
          from?factory.fruit?import?*

          class?AbstractFactory(object):
          ????"""抽象工廠(chǎng)"""
          ????__metaclass__?=?abc.ABCMeta

          [email protected]
          ????def?get_fruit(self):
          ????????pass
          接著,創(chuàng)建抽象工廠(chǎng)類(lèi)的 3 個(gè)子類(lèi),并重寫(xiě)方法,創(chuàng)建一個(gè)實(shí)例對(duì)象并返回
          class?AppleFactory(AbstractFactory):
          ????"""生產(chǎn)蘋(píng)果"""

          ????def?get_fruit(self):
          ????????return?Apple()

          class?BananaFactory(AbstractFactory):
          ????"""生產(chǎn)香蕉"""

          ????def?get_fruit(self):
          ????????return?Banana()

          class?OrangeFactory(AbstractFactory):
          ????"""生產(chǎn)橘子"""

          ????def?get_fruit(self):
          ????????return?Orange()
          最后的使用方式如下:
          if?__name__?==?'__main__':
          ????#?每個(gè)工廠(chǎng)負(fù)責(zé)生產(chǎn)自己的產(chǎn)品也避免了我們?cè)谛略霎a(chǎn)品時(shí)需要修改工廠(chǎng)的代碼,而只要增加相應(yīng)的工廠(chǎng)即可
          ????instance_apple?=?AppleFactory().get_fruit()
          ????instance_banana?=?BananaFactory().get_fruit()
          ????instance_orange?=?OrangeFactory().get_fruit()

          ????print(instance_apple)
          ????print(instance_banana)
          ????print(instance_orange)
          第 3 種,抽象工廠(chǎng)
          如果一個(gè)工廠(chǎng)要生產(chǎn)多個(gè)產(chǎn)品,使用工廠(chǎng)方法的話(huà),就需要編寫(xiě)很多工廠(chǎng)類(lèi),不太實(shí)用,使用抽象工廠(chǎng)就可以很好的解決這個(gè)問(wèn)題
          以川菜館和湘菜館炒兩個(gè)菜,毛血旺和小炒肉為例
          首先,創(chuàng)建川菜毛血旺、川菜小炒肉、湘菜毛血旺、湘菜小炒肉?4 個(gè)類(lèi)
          class?MaoXW_CC(object):
          ????"""川菜-毛血旺"""

          ????def?__str__(self):
          ????????return?"川菜-毛血旺"

          class?XiaoCR_CC(object):
          ????"""川菜-小炒肉"""

          ????def?__str__(self):
          ????????return?"川菜-小炒肉"

          class?MaoXW_XC(object):
          ????"""湘菜-毛血旺"""

          ????def?__str__(self):
          ????????return?"湘菜-毛血旺"

          class?XiaoCR_XC(object):
          ????"""湘菜-小炒肉"""

          ????def?__str__(self):
          ????????return?"湘菜-小炒肉"
          然后,定義一個(gè)抽象工廠(chǎng)類(lèi),內(nèi)部定義兩個(gè)方法,可以生成毛血旺和小炒肉
          class?AbstractFactory(object):
          ????"""
          ????抽象工廠(chǎng)
          ????既可以生產(chǎn)毛血旺,也可以生成小炒肉
          ????"""

          ????__metaclass__?=?abc.ABCMeta

          [email protected]
          ????def?product_maoxw(self):
          ????????pass

          [email protected]
          ????def?product_xiaocr(self):
          ????????pass
          接著,創(chuàng)建抽象工廠(chǎng)類(lèi)的兩個(gè)子類(lèi),川菜工廠(chǎng)和湘菜工廠(chǎng),重寫(xiě)方法,然后創(chuàng)建對(duì)應(yīng)的實(shí)例對(duì)象返回
          class?CCFactory(AbstractFactory):
          ????"""川菜館"""

          ????def?product_maoxw(self):
          ????????return?MaoXW_CC()

          ????def?product_xiaocr(self):
          ????????return?XiaoCR_CC()


          class?XCFactory(AbstractFactory):
          ????"""湘菜館"""

          ????def?product_maoxw(self):
          ????????return?MaoXW_XC()

          ????def?product_xiaocr(self):
          ????????return?XiaoCR_XC()
          最后,使用川菜工廠(chǎng)和湘菜工廠(chǎng)分別炒兩個(gè)菜
          if?__name__?==?'__main__':
          ????#?川菜炒兩個(gè)菜,分別是:毛血旺和小炒肉
          ????maoxw_cc?=?CCFactory().product_maoxw()
          ????xiaocr_cc?=?CCFactory().product_xiaocr()

          ????print(maoxw_cc,?xiaocr_cc)

          ????maoxw_xc?=?XCFactory().product_maoxw()
          ????xiaocr_xc?=?XCFactory().product_xiaocr()

          ????print(maoxw_xc,?xiaocr_xc)

          4. 最后

          單例模式和工廠(chǎng)模式是日常使用最為頻繁的兩種設(shè)計(jì)模式,下篇文章將聊聊后面 3 種設(shè)計(jì)模式,希望大家在留言區(qū)捧個(gè)場(chǎng)支持一下,月底統(tǒng)計(jì)常來(lái)留言的同學(xué)送書(shū),給個(gè)三連哈!你的支持,就是我原創(chuàng)的最佳動(dòng)力!



          大神來(lái)教大家玩服務(wù)器:
          安老師,某大廠(chǎng)互聯(lián)網(wǎng)公司的資深后端大神,有5年多的后端開(kāi)發(fā)經(jīng)驗(yàn),教大家玩轉(zhuǎn)云服務(wù)器玩Linux,安裝Python,安裝數(shù)據(jù)庫(kù),用Django+uwsigi+nginx web服務(wù)搭建網(wǎng)站,求職簡(jiǎn)歷網(wǎng)站搭建,寫(xiě)腳本部署股票基金機(jī)器人,還可以搭建個(gè)人網(wǎng)盤(pán)!

          星球的價(jià)格是一年88元,然后現(xiàn)在雙11期間有優(yōu)惠券20元,相當(dāng)于是68一年,算下來(lái)每個(gè)月6塊錢(qián),連半杯奶茶的錢(qián)都不到,一天才2毛錢(qián),非常劃算。





          推薦閱讀:

          入門(mén):?最全的零基礎(chǔ)學(xué)Python的問(wèn)題? |?零基礎(chǔ)學(xué)了8個(gè)月的Python??|?實(shí)戰(zhàn)項(xiàng)目?|學(xué)Python就是這條捷徑


          干貨:爬取豆瓣短評(píng),電影《后來(lái)的我們》?|?38年NBA最佳球員分析?|? ?從萬(wàn)眾期待到口碑撲街!唐探3令人失望? |?笑看新倚天屠龍記?|?燈謎答題王?|用Python做個(gè)海量小姐姐素描圖?|碟中諜這么火,我用機(jī)器學(xué)習(xí)做個(gè)迷你推薦系統(tǒng)電影


          趣味:彈球游戲? |?九宮格? |?漂亮的花?|?兩百行Python《天天酷跑》游戲!


          AI:?會(huì)做詩(shī)的機(jī)器人?|?給圖片上色?|?預(yù)測(cè)收入?|?碟中諜這么火,我用機(jī)器學(xué)習(xí)做個(gè)迷你推薦系統(tǒng)電影


          小工具:?Pdf轉(zhuǎn)Word,輕松搞定表格和水印!?|?一鍵把html網(wǎng)頁(yè)保存為pdf!|??再見(jiàn)PDF提取收費(fèi)!?|?用90行代碼打造最強(qiáng)PDF轉(zhuǎn)換器,word、PPT、excel、markdown、html一鍵轉(zhuǎn)換?|?制作一款釘釘?shù)蛢r(jià)機(jī)票提示器!?|60行代碼做了一個(gè)語(yǔ)音壁紙切換器天天看小姐姐!


          年度爆款文案

          瀏覽 68
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  美女裸身十八禁 | 久久久77777 | 三级黄,色毛片 | 91黄色小说 | 99精品视频在线 |