日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

再探泛型 API,感受 Python 對象的設計哲學

來源: 責編: 時間:2024-05-27 08:53:35 148觀看
導讀之前我們提到了泛型 API,這類 API 的特點是可以處理任意類型的對象,舉個例子。// 返回對象的長度PyObject_Size// 返回對象的某個屬性PyObject_GetAttr// 返回對象的哈希值PyObject_Hash// 將對象轉(zhuǎn)成字符串返回PyObjec

之前我們提到了泛型 API,這類 API 的特點是可以處理任意類型的對象,舉個例子。F0N28資訊網(wǎng)——每日最新資訊28at.com

// 返回對象的長度PyObject_Size// 返回對象的某個屬性PyObject_GetAttr// 返回對象的哈希值PyObject_Hash// 將對象轉(zhuǎn)成字符串返回PyObject_Str

對應到 Python 代碼中,就是下面這個樣子。F0N28資訊網(wǎng)——每日最新資訊28at.com

# PyObject_Sizeprint(len("古明地覺"))print(len([1, 2, 3]))"""43"""# PyObject_GetAttrprint(getattr("古明地覺", "lower"))print(getattr([1, 2, 3], "append"))print(getattr({}, "update"))"""<built-in method lower of str object at 0x7f081aa7e920><built-in method append of list object at 0x7f081adc1100><built-in method update of dict object at 0x7f081aa8fd80>"""# PyObject_Hashprint(hash("古明地覺"))print(hash(2.71))print(hash(123))"""81525063933782332031637148536541722626123"""# PyObject_Strprint(str("古明地覺"))print(str(object()))"""古明地覺<object object at 0x7fdfa0209d10>"""

這些 API 能處理任意類型的對象,這究竟是怎么辦到的?要想搞清楚這一點,還是要從 PyObject 入手。F0N28資訊網(wǎng)——每日最新資訊28at.com

我們知道對象在 C 看來就是一個結構體實例,并且結構體嵌套了 PyObject。F0N28資訊網(wǎng)——每日最新資訊28at.com

# 創(chuàng)建一個列表,讓變量 var 指向它var = [1, 2, 3]# 創(chuàng)建一個浮點數(shù),讓變量 var 指向它var = 2.71

列表對應的結構體是 PyListObject,浮點數(shù)對應的結構體是 PyFloatObject,變量 var 是指向?qū)ο蟮闹羔?。那么問題來了,憑啥一個變量可以指向不同類型的對象呢?或者說變量和容器里面為什么可以保存不同對象的指針呢?F0N28資訊網(wǎng)——每日最新資訊28at.com

原因在前面的文章中解釋的很詳細了,因為對象的指針會統(tǒng)一轉(zhuǎn)成 PyObject * 之后再交給變量保存,以創(chuàng)建列表為例。F0N28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片F0N28資訊網(wǎng)——每日最新資訊28at.com

當然創(chuàng)建浮點數(shù)也是同理,因此變量和容器里的元素本質(zhì)上就是一個泛型指針 PyObject *。而對象的指針在交給變量保存的時候,也都會先轉(zhuǎn)成 PyObject *,因為不管什么對象,它底層的結構體都嵌套了 PyObject。正是因為這個設計,變量才能指向任意的對象。F0N28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片F0N28資訊網(wǎng)——每日最新資訊28at.com

所以 Python 變量相當于一個便利貼,可以貼在任意對象上。F0N28資訊網(wǎng)——每日最新資訊28at.com

不過問題來了,由于對象的指針會統(tǒng)一轉(zhuǎn)成 PyObject * 之后再交給變量保存,那么變量怎么知道自己指向的是哪種類型的對象呢?相信你肯定知道答案:通過 ob_type 字段。F0N28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片F0N28資訊網(wǎng)——每日最新資訊28at.com

對象對應的結構體可以有很多個字段,比如 PyListObject,但變量能看到的只有前兩個字段。至于之后的字段是什么,則取決于對象的類型,總之對變量來說是不可見的,因為它是 PyObject *。F0N28資訊網(wǎng)——每日最新資訊28at.com

所以變量會先通過 ob_type 字段獲取對象的類型,如果 ob_type 字段的值為 &PyList_Type,那么變量指向的就是 PyListObject。如果 ob_type 字段的值為 &PyFloat_Type,那么變量指向的就是 PyFloatObject,其它類型同理。F0N28資訊網(wǎng)——每日最新資訊28at.com

當?shù)玫搅藢ο蟮念愋?,那么再轉(zhuǎn)成相應的指針即可,假設 ob_type 是 &PyList_Type,那么變量會再轉(zhuǎn)成 PyListObject *,這樣就可以操作列表的其它字段了。F0N28資訊網(wǎng)——每日最新資訊28at.com

所以我們再總結一下:F0N28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片F0N28資訊網(wǎng)——每日最新資訊28at.com

變量和容器里的元素只能保存相同的指針類型,而不同類型的對象,其底層的結構體是不同的。但這些結構體無一例外都嵌套了 PyObject,因此它們的指針會統(tǒng)一轉(zhuǎn)成 PyObject * 之后再交給變量保存。F0N28資訊網(wǎng)——每日最新資訊28at.com

然后變量在操作對象時,會先通過 ob_type 判斷對象的類型,假如是 &PyList_Type,那么會再轉(zhuǎn)成 PyListObject *,其它類型同理。F0N28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片F0N28資訊網(wǎng)——每日最新資訊28at.com

相信你已經(jīng)知道為什么泛型 API 可以處理任意類型的對象了,以 PyObject_GetAttr 為例,它內(nèi)部會調(diào)用類型對象的 tp_getattro。F0N28資訊網(wǎng)——每日最新資訊28at.com

// 等價于 getattr(v, name)PyObject *PyObject_GetAttr(PyObject *v, PyObject *name){       // 獲取對象 v 的類型對象    PyTypeObject *tp = Py_TYPE(v);    PyObject* result = NULL;    // 如果類型對象實現(xiàn)了 tp_getattro,那么進行調(diào)用    // 等價于 Python 中的 type(v).__getattr__(v, name)    if (tp->tp_getattro != NULL) {        result = (*tp->tp_getattro)(v, name);    }    // 否則會退化為 tp_getattr,它要求屬性名稱必須是 C 字符串    // 不過 tp_getattr 已經(jīng)廢棄,應該使用 tp_getattro    else if (tp->tp_getattr != NULL) {        const char *name_str = PyUnicode_AsUTF8(name);        if (name_str == NULL) {            return NULL;        }        result = (*tp->tp_getattr)(v, (char *)name_str);    }    // 否則說明對象 v 沒有指定屬性    else {        PyErr_Format(PyExc_AttributeError,                    "'%.100s' object has no attribute '%U'",                    tp->tp_name, name);    }    return result;}

函數(shù)先通過 ob_type 找到對象的類型,然后通過類型對象的 tp_getattro 調(diào)用對應的屬性查找函數(shù)。所以 PyObject_GetAttr 會根據(jù)對象的類型,調(diào)用不同的屬性查找函數(shù),因此這就是泛型 API 能處理任意對象的秘密。F0N28資訊網(wǎng)——每日最新資訊28at.com

我們再以 Python 為例:F0N28資訊網(wǎng)——每日最新資訊28at.com

class A:    def __getattr__(self, item):        return f"class:A,item:{item}"class B:    def __getattr__(self, item):        return f"class:B,item:{item}"a = A()b = B()print(getattr(a, "some_attr"))print(getattr(b, "some_attr"))"""class:A,item:some_attrclass:B,item:some_attr"""# 以上等價于print(type(a).__getattr__(a, "some_attr"))print(type(b).__getattr__(b, "some_attr"))"""class:A,item:some_attrclass:B,item:some_attr"""

在 Python 里的表現(xiàn)和源碼是一致的,我們再舉個 iter 的例子:F0N28資訊網(wǎng)——每日最新資訊28at.com

data = [1, 2, 3]print(iter(data))print(type(data).__iter__(data))"""<list_iterator object at 0x7fb8200f29a0><list_iterator object at 0x7fb8200f29a0>"""

如果一個對象支持迭代器操作,那么它的類型對象一定實現(xiàn)了 __iter__,通過 type(data) 可以獲取到類型對象,然后將 data 作為參數(shù)調(diào)用 __iter__ 即可。F0N28資訊網(wǎng)——每日最新資訊28at.com

所以通過 ob_type 字段,這些泛型 API 實現(xiàn)了類似多態(tài)的效果,一個函數(shù),多種實現(xiàn)。F0N28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-90852-0.html再探泛型 API,感受 Python 對象的設計哲學

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: Vue3 新玩法!我能操控計算屬性 Computed!

下一篇: Python 類型注解與檢查:讓代碼“開口說話”的八個妙招

標簽:
  • 熱門焦點
  • MIX Fold3包裝盒泄露 新機本月登場

    小米的全新折疊屏旗艦MIX Fold3將于本月發(fā)布,近日該機的真機包裝盒在網(wǎng)上泄露。從圖上來看,新的MIX Fold3包裝盒在外觀設計方面延續(xù)了之前的方案,變化不大,這也是目前小米旗艦
  • 對標蘋果的靈動島 華為帶來實況窗功能

    繼蘋果的靈動島之后,華為也在今天正式推出了“實況窗”功能。據(jù)今天鴻蒙OS 4.0的現(xiàn)場演示顯示,華為的實況窗可以更高效的展現(xiàn)出實時通知,比如鎖屏上就能看到外賣、打車、銀行
  • 7月安卓手機好評榜:三星S23Ultra好評率第一

    性能榜和性價比榜之后,我們來看最后的安卓手機好評榜,數(shù)據(jù)來源安兔兔評測,收集時間2023年7月1日至7月31日,僅限國內(nèi)市場。第一名:三星Galaxy S23 Ultra好評率:95.71%在即將迎來新
  • 28個SpringBoot項目中常用注解,日常開發(fā)、求職面試不再懵圈

    前言在使用SpringBoot開發(fā)中或者在求職面試中都會使用到很多注解或者問到注解相關的知識。本文主要對一些常用的注解進行了總結,同時也會舉出具體例子,供大家學習和參考。注解
  • 讓我們一起聊聊文件的操作

    文件【1】文件是什么?文件是保存數(shù)據(jù)的地方,是數(shù)據(jù)源的一種,比如大家經(jīng)常使用的word文檔、txt文件、excel文件、jpg文件...都是文件。文件最主要的作用就是保存數(shù)據(jù),它既可以保
  • 使用AIGC工具提升安全工作效率

    在日常工作中,安全人員可能會涉及各種各樣的安全任務,包括但不限于:開發(fā)某些安全工具的插件,滿足自己特定的安全需求;自定義github搜索工具,快速查找所需的安全資料、漏洞poc、exp
  • 花7萬退貨退款無門:誰在縱容淘寶珠寶商家造假?

    來源:極點商業(yè)作者:楊銘在淘寶購買珠寶玉石后,因為保證金不夠賠付,店鋪關閉,退貨退款難、維權無門的比比皆是。&ldquo;提供相關產(chǎn)品鑒定證書,支持全國復檢,可以30天無理由退換貨。&
  • iQOO Neo8 Pro評測:旗艦雙芯加持 最強性能游戲旗艦

    【Techweb評測】去年10月,iQOO推出了一款Neo7手機,該機搭載了聯(lián)發(fā)科天璣9000+,配備獨顯芯片Pro+,帶來了同價位段最佳的游戲體驗,一經(jīng)上市便受到了諸多用
  • 利用職權私自解除被封帳號 Meta開除20多名員工

    11月18日消息,據(jù)外媒援引知情人士表示,過去一年時間內(nèi),F(xiàn)acebook母公司Meta解雇或處罰了20多名員工以及合同工,指控這些人通過內(nèi)部系統(tǒng)以不當方式重置用戶帳號,其
Top 主站蜘蛛池模板: 囊谦县| 玛多县| 晋州市| 绥棱县| 麻江县| 兴安盟| 呼伦贝尔市| 宝清县| 城口县| 田林县| 札达县| 锦州市| 石家庄市| 罗定市| 两当县| 弥渡县| 郸城县| 聂荣县| 行唐县| 武胜县| 庆安县| 封丘县| 电白县| 南康市| 扎鲁特旗| 乐亭县| 子洲县| 德清县| 依兰县| 曲沃县| 思南县| 德令哈市| 石渠县| 福建省| 金门县| 沅江市| 丁青县| 汶上县| 乌拉特中旗| 怀集县| 略阳县|