乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Python 的 enum 模塊源碼分析

       xiaoyimin 2019-02-13

      成員名不允許重復(fù)

      這部分我的第一個想法是去控制__dict__中的 key 。但這樣的方式并不好,__dict__ 范圍大,它包含該類的所有屬性和方法。而不單單是枚舉的命名空間。我在源碼中發(fā)現(xiàn) enum 使用另一個方法。通過 __prepare__ 魔術(shù)方法可以返回一個類字典實例,在該實例 使用__prepare__ 魔術(shù)方法自定義命名空間,在該空間內(nèi)限定成員名不允許重復(fù)。

      再看看 Enum 模塊的具體實現(xiàn):

      模塊中的_EnumDict 創(chuàng)建了_member_names 列表來存儲成員名,這是因為不是所有的命名空間內(nèi)的成員都是枚舉的成員。比如 __str__, __new__ 等魔術(shù)方法就不是了,所以這邊的 __setitem__ 需要做一些過濾:

      模塊考慮的會更全面。

      每個成員都有名稱屬性和值屬性

      上述的代碼中,Color.red 取得的值是 1。而 eumu 模塊中,定義的枚舉類中,每個成員都是有名稱和屬性值的;并且細心的話還會發(fā)現(xiàn) Color.red 是 Color 的示例。這樣的情況是如何來實現(xiàn)的呢。

      還是用元類來完成,在元類的 __new__ 中實現(xiàn),具體的思路是,先創(chuàng)建目標類,然后為每個成員都創(chuàng)建一樣的類,再通過 setattr 的方式將后續(xù)的類作為屬性添加到目標類中,偽代碼如下:

      來看下一個可運行的demo:

      enum 模塊在讓每個成員都有名稱和值的屬性的實現(xiàn)思路是一樣的(代碼我就不貼了)。EnumMeta.__new__ 是該模塊的重點,幾乎所有枚舉的特性都在這個函數(shù)實現(xiàn)。

      當成員值相同時,第二個成員是第一個成員的別名

      從這節(jié)開始就不再使用自己實現(xiàn)的類的說明了,而是通過拆解 enum 模塊的代碼來說明其實現(xiàn)了,從模塊的使用特性中可以知道,如果成員值相同,后者會是前者的一個別名:

      從這可以知道,red和_red是同一對象。這又要怎么實現(xiàn)呢?

      元類會為枚舉類創(chuàng)建_member_map_ 屬性來存儲成員名與成員的映射關(guān)系,如果發(fā)現(xiàn)創(chuàng)建的成員的值已經(jīng)在映射關(guān)系中了,就會用映射表中的對象來取代:

      從代碼上來看,即使是成員值相同,還是會先為他們都創(chuàng)建對象,不過后創(chuàng)建的很快就會被垃圾回收掉了(我認為這邊是有優(yōu)化空間的)。通過與_member_map_ 映射表做對比,用以創(chuàng)建該成員值的成員取代后續(xù),但兩者成員名都會在 _member_map_中,如例子中的red和_red 都在該字典,但他們指向的是同一個對象。

      屬性_member_names_只會記錄第一個,這將會與枚舉的迭代有關(guān)。

      可以通過成員值來獲取成員

      枚舉類中的成員都是單例模式,元類創(chuàng)建的枚舉類中還維護了值到成員的映射關(guān)系 _value2member_map_:

      然后在 Enum 的__new__返回該單例即可:

      迭代的方式遍歷成員

      枚舉類支持迭代的方式遍歷成員,按定義的順序,如果有值重復(fù)的成員,只獲取重復(fù)的第一個成員。對于重復(fù)的成員值只獲取第一個成員,正好屬性_member_names_只會記錄第一個:

      總結(jié)

      enum 模塊的核心特性的實現(xiàn)思路就是這樣,幾乎都是通過元類黑魔法來實現(xiàn)的。對于成員之間不能做比較大小但可以做等值比較。這反而不需要講,這其實繼承自 object 就是這樣的,不用額外做什么就有的“特性”了。

      總之,enum 模塊相對獨立,且代碼量不多,對于想知道元類編程可以閱讀一下,教科書式教學(xué),還有單例模式等,值得一讀。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多