最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python 中類的構(gòu)造方法 __New__的妙用

 更新時(shí)間:2021年10月20日 10:16:22   作者:somenzz  
這篇文章主要介紹了Python 中類的構(gòu)造方法 New的妙用,Python 的類中,所有以雙下劃線__包起來的方法,叫魔術(shù)方法,魔術(shù)方法在類或?qū)ο蟮哪承┦录l(fā)出后可以自動(dòng)執(zhí)行,讓類具有神奇的魔力。下面就來學(xué)習(xí)文章的詳細(xì)內(nèi)容把

1、概述

python 的類中,所有以雙下劃線__包起來的方法,叫魔術(shù)方法,魔術(shù)方法在類或?qū)ο蟮哪承┦录l(fā)出后可以自動(dòng)執(zhí)行,讓類具有神奇的魔力,比如常見的構(gòu)造方法__new__ 、初始化方法__init__ 、析構(gòu)方法__del__ ,今天來聊一聊__new__的妙用,主要分享以下幾點(diǎn):

  • __new__ 和 __init__ 的區(qū)別
  • 應(yīng)用1:改變內(nèi)置的不可變類型
  • 應(yīng)用2:實(shí)現(xiàn)一個(gè)單例
  • 應(yīng)用3:客戶端緩存
  • 應(yīng)用4:不同文件不同的解密方法
  • 應(yīng)用5:Metaclasses

2、__new__ 和 __init__ 的區(qū)別

  • 調(diào)用時(shí)機(jī)不同:new 是真正創(chuàng)建實(shí)例的方法,init 用于實(shí)例的初始化,new 先于 init 運(yùn)行。
  • 返回值不同,new 返回一個(gè)類的實(shí)例,而 init 不返回任何信息。
  • new class 的方法,而 init 是對(duì)象的方法。

示例代碼:

class A: 
    def __new__(cls, *args, **kwargs): 
        print("new", cls, args, kwargs) 
        return super().__new__(cls) 
 
    def __init__(self, *args, **kwargs): 
        print("init", self, args, kwargs) 
 
 
def how_object_construction_works(): 
    x = A(1, 2, 3, x=4) 
    print(x)     
    print("===================") 
    x = A.__new__(A, 1, 2, 3, x=4) 
    if isinstance(x, A): 
        type(x).__init__(x, 1, 2, 3, x=4) 
    print(x) 
 
if __name__ == "__main__": 
    how_object_construction_works() 


上述代碼定義了一個(gè)類 A,在調(diào)用 A(1, 2, 3, x=4) 時(shí)先執(zhí)行 new,再執(zhí)行 init,等價(jià)于:

x = A.__new__(A, 1, 2, 3, x=4) 
if isinstance(x, A): 
    type(x).__init__(x, 1, 2, 3, x=4) 


代碼的運(yùn)行結(jié)果如下:

new <class '__main__.A'> (1, 2, 3) {'x': 4} 
init <__main__.A object at 0x7fccaec97610> (1, 2, 3) {'x': 4} 
<__main__.A object at 0x7fccaec97610> 
=================== 
new <class '__main__.A'> (1, 2, 3) {'x': 4} 
init <__main__.A object at 0x7fccaec97310> (1, 2, 3) {'x': 4} 
<__main__.A object at 0x7fccaec97310> 


new 的主要作用就是讓程序員可以自定義類的創(chuàng)建行為,以下是其主要應(yīng)用場(chǎng)景:

3、應(yīng)用1:改變內(nèi)置的不可變類型

我們知道,元組是不可變類型,但是我們繼承 tuple ,然后可以在 new 中,對(duì)其元組的元素進(jìn)行修改,因?yàn)?new 返回之前,元組還不是元組,這在 init 函數(shù)中是無(wú)法實(shí)現(xiàn)的。比如說,實(shí)現(xiàn)一個(gè)大寫的元組,代碼如下:

class UppercaseTuple(tuple): 
    def __new__(cls, iterable): 
        upper_iterable = (s.upper() for s in iterable) 
        return super().__new__(cls, upper_iterable) 
 
    # 以下代碼會(huì)報(bào)錯(cuò),初始化時(shí)是無(wú)法修改的 
    # def __init__(self, iterable): 
    #     print(f'init {iterable}') 
    #     for i, arg in enumerate(iterable): 
    #         self[i] = arg.upper() 
 
if __name__ == '__main__': 
    print("UPPERCASE TUPLE EXAMPLE") 
    print(UppercaseTuple(["hello", "world"])) 
 
# UPPERCASE TUPLE EXAMPLE 
# ('HELLO', 'WORLD') 

4、應(yīng)用2:實(shí)現(xiàn)一個(gè)單例

class Singleton: 
    _instance = None 
 
    def __new__(cls, *args, **kwargs): 
        if cls._instance is None: 
            cls._instance = super().__new__(cls, *args, **kwargs) 
        return cls._instance 
 
 
if __name__ == "__main__": 
 
    print("SINGLETON EXAMPLE") 
    x = Singleton() 
    y = Singleton() 
    print(f"{x is y=}") 
# SINGLETON EXAMPLE 
# x is y=True 

5、應(yīng)用3:客戶端緩存

當(dāng)客戶端的創(chuàng)建成本比較高時(shí),比如讀取文件或者數(shù)據(jù)庫(kù),可以采用以下方法,同一個(gè)客戶端屬于同一個(gè)實(shí)例,節(jié)省創(chuàng)建對(duì)象的成本,這本質(zhì)就是多例模式。

class Client: 
    _loaded = {} 
    _db_file = "file.db" 
 
    def __new__(cls, client_id): 
        if (client := cls._loaded.get(client_id)) is not None: 
            print(f"returning existing client {client_id} from cache") 
            return client 
        client = super().__new__(cls) 
        cls._loaded[client_id] = client 
        client._init_from_file(client_id, cls._db_file) 
        return client 
 
    def _init_from_file(self, client_id, file): 
        # lookup client in file and read properties 
        print(f"reading client {client_id} data from file, db, etc.") 
        name = ... 
        email = ... 
        self.name = name 
        self.email = email 
        self.id = client_id 
 
 
if __name__ == '__main__': 
    print("CLIENT CACHE EXAMPLE") 
    x = Client(0) 
    y = Client(0) 
    print(f"{x is y=}") 
    z = Client(1) 
# CLIENT CACHE EXAMPLE 
# reading client 0 data from file, db, etc. 
# returning existing client 0 from cache 
# x is y=True 
# reading client 1 data from file, db, etc. 

6、應(yīng)用4:不同文件不同的解密方法

先在腳本所在目錄創(chuàng)建三個(gè)文件:plaintext_hello.txt、rot13_hello.txt、otp_hello.txt,程序會(huì)根據(jù)不同的文件選擇不同的解密算法

import codecs 
import itertools 
 
 
class EncryptedFile: 
    _registry = {}  # 'rot13' -> ROT13Text 
 
    def __init_subclass__(cls, prefix, **kwargs): 
        super().__init_subclass__(**kwargs) 
        cls._registry[prefix] = cls 
 
    def __new__(cls, path: str, key=None): 
        prefix, sep, suffix = path.partition(":///") 
        if sep: 
            file = suffix 
        else: 
            file = prefix 
            prefix = "file" 
        subclass = cls._registry[prefix] 
        obj = object.__new__(subclass) 
        obj.file = file 
        obj.key = key 
        return obj 
 
    def read(self) -> str: 
        raise NotImplementedError 
 
 
class Plaintext(EncryptedFile, prefix="file"): 
    def read(self): 
        with open(self.file, "r") as f: 
            return f.read() 
 
 
class ROT13Text(EncryptedFile, prefix="rot13"): 
    def read(self): 
        with open(self.file, "r") as f: 
            text = f.read() 
        return codecs.decode(text, "rot_13") 
 
 
class OneTimePadXorText(EncryptedFile, prefix="otp"): 
    def __init__(self, path, key): 
        if isinstance(self.key, str): 
            self.key = self.key.encode() 
 
    def xor_bytes_with_key(self, b: bytes) -> bytes: 
        return bytes(b1 ^ b2 for b1, b2 in zip(b, itertools.cycle(self.key))) 
 
    def read(self): 
        with open(self.file, "rb") as f: 
            btext = f.read() 
        text = self.xor_bytes_with_key(btext).decode() 
        return text 
 
 
if __name__ == "__main__": 
    print("ENCRYPTED FILE EXAMPLE") 
    print(EncryptedFile("plaintext_hello.txt").read()) 
    print(EncryptedFile("rot13:///rot13_hello.txt").read()) 
    print(EncryptedFile("otp:///otp_hello.txt", key="1234").read()) 
# ENCRYPTED FILE EXAMPLE 
# plaintext_hello.txt 
# ebg13_uryyb.gkg 
# ^FCkYW_X^GLE 

到此這篇關(guān)于Python 中類的構(gòu)造方法 New的妙用的文章就介紹到這了,更多相關(guān)Python 中類的構(gòu)造方法 New內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • pytorch邏輯回歸實(shí)現(xiàn)步驟詳解

    pytorch邏輯回歸實(shí)現(xiàn)步驟詳解

    這篇文章主要為大家詳細(xì)介紹了Pytorch實(shí)現(xiàn)邏輯回歸分類,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-10-10
  • django用戶登錄驗(yàn)證的完整示例代碼

    django用戶登錄驗(yàn)證的完整示例代碼

    這篇文章主要給大家介紹了關(guān)于django用戶登錄驗(yàn)證的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring django具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • Python Pandas實(shí)現(xiàn)根據(jù)多列的值生成新的列

    Python Pandas實(shí)現(xiàn)根據(jù)多列的值生成新的列

    在 Pandas 中,可以根據(jù) 多列的值 生成新的列,這篇文章主要和大家詳細(xì)介紹了一些常見的方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下
    2026-02-02
  • 教你用 Python 實(shí)現(xiàn)微信跳一跳(Mac+iOS版)

    教你用 Python 實(shí)現(xiàn)微信跳一跳(Mac+iOS版)

    這幾天看網(wǎng)上好多微信跳一跳破解了,不過都是安卓的,無(wú)奈蘋果不是開源也沒辦法。本文給大家分享用 Python 來玩微信跳一跳(Mac+iOS版),具體實(shí)現(xiàn)代碼大家參考下本文
    2018-01-01
  • python中@contextmanager裝飾器的用法詳解

    python中@contextmanager裝飾器的用法詳解

    這篇文章主要介紹了python中@contextmanager裝飾器的用法詳解,@contextmanager 的作用就是我們可以把一個(gè)非自定義類改成一個(gè)上下文管理器,需要的朋友可以參考下
    2023-07-07
  • python如何進(jìn)入交互模式

    python如何進(jìn)入交互模式

    在本篇內(nèi)容中小編給大家分享了關(guān)于python進(jìn)入交互模式的方法,對(duì)此有需要的朋友們可以跟著學(xué)習(xí)下。
    2020-07-07
  • python同時(shí)替換多個(gè)字符串方法示例

    python同時(shí)替換多個(gè)字符串方法示例

    這篇文章主要介紹了python同時(shí)替換多個(gè)字符串方法示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Sanic框架異常處理與中間件操作實(shí)例分析

    Sanic框架異常處理與中間件操作實(shí)例分析

    這篇文章主要介紹了Sanic框架異常處理與中間件操作,結(jié)合實(shí)例形式較為詳細(xì)的分析了Sanic框架拋出異常、異常處理、中間件、監(jiān)聽器相關(guān)原理與操作技巧,需要的朋友可以參考下
    2018-07-07
  • python 階乘累加和的實(shí)例

    python 階乘累加和的實(shí)例

    今天小編就為大家分享一篇python 階乘累加和的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-02-02
  • python數(shù)據(jù)寫入列表并導(dǎo)出折線圖

    python數(shù)據(jù)寫入列表并導(dǎo)出折線圖

    這篇文章主要介紹了python數(shù)據(jù)寫入列表并導(dǎo)出折線圖,文章以舉例展開對(duì)文章主題的介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-01-01

最新評(píng)論

年辖:市辖区| 基隆市| 贵溪市| 宜昌市| 东城区| 麻江县| 娄底市| 方正县| 呼和浩特市| 监利县| 丹寨县| 娄底市| 个旧市| 达日县| 当阳市| 酒泉市| 台东市| 营口市| 本溪市| 大连市| 时尚| 察哈| 威信县| 达孜县| 夹江县| 东兰县| 诸城市| 徐水县| 中山市| 曲阳县| 巨野县| 和田县| 罗田县| 黑水县| 绥芬河市| 潞城市| 凯里市| 龙胜| 梨树县| 宝兴县| 永胜县|