第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

是否有允許您正確覆蓋魔術(shù)方法的 PyObject 類的實(shí)現(xiàn)?

是否有允許您正確覆蓋魔術(shù)方法的 PyObject 類的實(shí)現(xiàn)?

一只斗牛犬 2022-12-20 15:28:44
list所以我在一本書中讀到,如果你想從,dict或等內(nèi)置類型擴(kuò)展str,并想覆蓋魔術(shù)方法,你應(yīng)該分別使用UserList,UserDict和UserString來自collections模塊。顯然,這是因?yàn)榛愂窃?CPython 中實(shí)現(xiàn)的,其中這些方法不會相互調(diào)用,因此覆蓋它們不會產(chǎn)生不良影響。我想知道是否與UserList類等類似,是否存在一個可用于“正確”從類擴(kuò)展的object類。我查看了PyObject 文檔并找到了這篇文章以及這篇文章,但我既不想在 C 中擴(kuò)展,也不想說出來。collections我在模塊或其他任何地方都找不到任何東西。
查看完整描述

1 回答

?
一只萌萌小番薯

TA貢獻(xiàn)1795條經(jīng)驗(yàn) 獲得超7個贊

正如評論中所述 - 沒有這樣的東西,也不需要它 - 中的所有魔術(shù)方法都o(jì)bject可以被覆蓋并且可以正常工作。


字典、列表和其他集合會發(fā)生什么,正如 MisterMiyagi 在評論中解釋的那樣,例如,dictget不會使用該__getitem__方法,因此如果您要自定義其行為,您還必須重寫get. 正確解決這個問題的類,允許人們用最少的可重用代碼創(chuàng)建完全可用的映射、序列和集合,這些類是在collections.abc模塊中定義的。


現(xiàn)在,如果您希望其中一種魔術(shù)方法對一個對象的類而不是該類的實(shí)例起作用,則必須在該類的類中實(shí)現(xiàn)這些方法——這就是“元類”。


這與“超類”有很大不同——超類定義了子類繼承的方法和屬性,這些方法和屬性在子類中可用。但是類上的魔術(shù)方法只影響實(shí)例,而不影響類本身(__init_subclass__, 和當(dāng)然除外__new__,它可以更改為做其他事情而不是創(chuàng)建新實(shí)例)。


元類控制類的構(gòu)建方式 (使用__new__,__init__和__call__方法) - 并且允許擁有關(guān)于它們?nèi)绾瓮ㄟ^魔術(shù)方法表現(xiàn)的方法 - 我認(rèn)為元類中的魔術(shù)方法如何在類中工作沒有特殊情況,與它們在類與普通實(shí)例的關(guān)系中的工作相比。如果您在元類上實(shí)現(xiàn)__add__, __getitem__,__len__所有這些都將適用于使用該元類創(chuàng)建的類。


如果您不想在元類本身中為該類編寫魔術(shù)方法,可以做的是創(chuàng)建一個元類,該元類將在被調(diào)用時自動創(chuàng)建另一個動態(tài)元類,并復(fù)制 dunder 方法到那個班級。但很難將其視為任何嚴(yán)肅應(yīng)用程序中的“健康”設(shè)計(jì)——將魔法方法應(yīng)用于類已經(jīng)有點(diǎn)過頭了——盡管在某些情況下這樣做很方便。


因此,例如,如果您希望一個類具有一個__geitem__允許您檢索該類的所有實(shí)例的類,這將起作用:


class InstanceRegister(type):

    def __init__(cls, name, bases, namespace, **kw):

        super().__init__(name, bases, namespace, **kw)


        cls._instances = []


        original_new = cls.__new__

        def new_wrapper(cls, *args, **kw):

            if original_new is object.__new__:

                instance = original_new(cls)

            else:

                instance = original_new(cls, *args, **kw)

            cls._instances.append(instance)

            return instance


        cls.__new__ = new_wrapper


    def __len__(cls):

        return len(cls._instances)


    def __getitem__(cls, item):

        return cls._instances[item]

這將起作用,正如在本次互動會議中所顯示的那樣:


In [26]: class A(metaclass=InstanceRegister): pass                                                                                   


In [27]: a = A()                                                                                                                     


In [28]: len(A)                                                                                                                      

Out[28]: 1


In [29]: A[0] is a                                                                                                                   

Out[29]: True


查看完整回答
反對 回復(fù) 2022-12-20
  • 1 回答
  • 0 關(guān)注
  • 96 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號