1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        聊聊 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ì)模式,它們是:單例模式、工廠模式、構(gòu)建者模式、代理模式、觀察者模式

        2. 單例模式

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

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

        第 1 種,重寫?__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è)單例裝飾器,將類的定義隱藏到閉包函數(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

        使用上面裝飾器的類,構(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)建的單例并不適用于多線程

        要保證多線程中構(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í)候,在線程任務(wù)中實(shí)例化對(duì)象,運(yùn)行線程即可

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

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

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

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

        3. 工廠模式

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

        ????def?__repr__(self):
        ????????return?"蘋果"


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

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


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

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

        ????@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)單工廠,返回對(duì)應(yīng)的實(shí)例
        ????instance_apple?=?FactorySimple.get_fruit('a')
        ????instance_banana?=?FactorySimple.get_fruit('b')
        ????instance_orange?=?FactorySimple.get_fruit('o')
        第 2 種,工廠方法
        工廠方法將創(chuàng)建對(duì)象的工作讓相應(yīng)的工廠子類去實(shí)現(xiàn),保證在新增工廠類時(shí),不用修改原有代碼
        首先,創(chuàng)建一個(gè)抽象公共工廠類,并定義一個(gè)生產(chǎn)對(duì)象的方法
        import?abc
        from?factory.fruit?import?*

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

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

        ????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è)工廠負(fù)責(zé)生產(chǎn)自己的產(chǎn)品也避免了我們?cè)谛略霎a(chǎn)品時(shí)需要修改工廠的代碼,而只要增加相應(yī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 種,抽象工廠
        如果一個(gè)工廠要生產(chǎn)多個(gè)產(chǎn)品,使用工廠方法的話,就需要編寫很多工廠類,不太實(shí)用,使用抽象工廠就可以很好的解決這個(gè)問(wèn)題
        以川菜館和湘菜館炒兩個(gè)菜,毛血旺和小炒肉為例
        首先,創(chuàng)建川菜毛血旺、川菜小炒肉、湘菜毛血旺、湘菜小炒肉?4 個(gè)類
        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è)抽象工廠類,內(nèi)部定義兩個(gè)方法,可以生成毛血旺和小炒肉
        class?AbstractFactory(object):
        ????"""
        ????抽象工廠
        ????既可以生產(chǎn)毛血旺,也可以生成小炒肉
        ????"""

        ????__metaclass__?=?abc.ABCMeta

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

        [email protected]
        ????def?product_xiaocr(self):
        ????????pass
        接著,創(chuàng)建抽象工廠類的兩個(gè)子類,川菜工廠和湘菜工廠,重寫方法,然后創(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()
        最后,使用川菜工廠和湘菜工廠分別炒兩個(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. 最后

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



        大神來(lái)教大家玩服務(wù)器:
        安老師,某大廠互聯(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)站搭建,寫腳本部署股票基金機(jī)器人,還可以搭建個(gè)人網(wǎng)盤!

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





        推薦閱讀:

        入門:?最全的零基礎(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,輕松搞定表格和水?。?/a>?|?一鍵把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)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            少妇一级淫免费观看 | 亚洲精品一区二区无码日本蜜桃 | 欧美色图网站 | 精品少妇一区二区三区在线观看 | 18禁 成人黄网站免费视频 | 成人免费精品视频 | www.黄色网址.com | 无码一区二区三区三 | 91精品久久久无码人妻 | 天天鲁天天爱天天做 |