您好,登錄后才能下訂單哦!
這篇文章主要介紹“怎么理解Python內(nèi)置對(duì)象”,在日常操作中,相信很多人在怎么理解Python內(nèi)置對(duì)象問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”怎么理解Python內(nèi)置對(duì)象”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!
所謂特別的寫法就是下面這個(gè):
# 用 ... 替代 pass def foo(): ...
它是中文標(biāo)點(diǎn)符號(hào)的半個(gè)省略號(hào),也即由英文的 3 個(gè)點(diǎn)組成。如果你是第一次看到,很可能會(huì)覺得奇怪:這玩意是怎么回事?PS:如果你知道它,仔細(xì)看過本文后,你同樣可能會(huì)覺得奇怪!
1. 認(rèn)識(shí)一下“...”內(nèi)置常量
事實(shí)上,它是 Python 3 中的一個(gè)內(nèi)置對(duì)象,有個(gè)正式的名字叫作——Ellipsis,翻譯成中文就是“省略號(hào)”。
更準(zhǔn)確地說,它是一個(gè)內(nèi)置常量(Built-in Constant),是 6 大內(nèi)置常量之一(另外幾個(gè)是 None、False、True、NotImplemented、__debug__)。
關(guān)于這個(gè)對(duì)象的基礎(chǔ)性質(zhì),下面給出了一張截圖,你們應(yīng)該能明白我的意思:
“...“并不神秘,它只是一個(gè)可能不多見的符號(hào)型對(duì)象而已。用它替換 pass,在語法上并不會(huì)報(bào)錯(cuò),因?yàn)?Python 允許一個(gè)對(duì)象不被賦值引用。
嚴(yán)格來說, 這是旁門左道,在語義上站不住腳——把“...”或其它常量或已被賦值的變量放在一個(gè)空的縮進(jìn)代碼塊中,它們是與動(dòng)作無關(guān)的,只能表達(dá)出“這有個(gè)沒用的對(duì)象,不用管它”。
Python 允許這些不被實(shí)際使用的對(duì)象存在,然而聰明的 IDE 應(yīng)該會(huì)有所提示(我用的是Pycharm),比如告訴你:Statement seems to have no effect 。
但是“...”這個(gè)常量似乎受到了特殊對(duì)待,我的 IDE 上沒有作提示。
很多人已經(jīng)習(xí)慣上把它當(dāng)成 pass 那樣的空操作來用了(在最早引入它的郵件組討論中,就是舉了這種用法的例子)。但我本人還是傾向于使用 pass,不知道你是怎么想的呢?
2. 奇怪的 Ellipsis 和 ...
... 在 PEP-3100 中被引入,最早合入在 Python 3.0 版本,而 Ellipsis 則在更早的版本中就已包含。
雖然官方說它們是同一個(gè)對(duì)象的兩種寫法,而且說成是單例的(singleton),但我還發(fā)現(xiàn)一個(gè)非常奇怪的現(xiàn)象,與文檔的描述是沖突的:
如你所見,賦值給 ... 時(shí)會(huì)報(bào)錯(cuò)SyntaxError: cannot assign to Ellipsis ,然而 Ellipsis 卻可以被賦值,它們的行為根本就不同嘛!被賦值之后,Ellipsis 的內(nèi)存地址以及類型屬性都改變了,它成了一個(gè)“變量”,不再是常量。
作為對(duì)比,給 True 或 None 之類的常量賦值時(shí),會(huì)報(bào)錯(cuò)SyntaxError: cannot assign to XXX,但是給 NotImplemented 常量賦值時(shí)不會(huì)報(bào)錯(cuò)。
眾所周知,在 Python 2 中也可以給布爾對(duì)象(True/False)賦值,然而 Python 3 已經(jīng)把它們改造成不可修改的。
所以有一種可能的解釋:Ellipsis 和 NotImplemented 是 Python 2 時(shí)代的遺留產(chǎn)物,為了兼容性或者只是因?yàn)楹诵拈_發(fā)者遺漏了,所以它們?cè)诋?dāng)前版本(3.8)中還可以被賦值修改。
... 出生在 Python 3 的時(shí)代,或許在將來會(huì)完全取代 Ellipsis。目前兩者共存,它們不一致的行為值得我們注意。我的建議:只使用"..."吧,就當(dāng) Ellipsis 已經(jīng)被淘汰了。
3. 為什么要使用“...”對(duì)象?
接下來,讓我們回到標(biāo)題的問題:Python 為什么要使用“...”對(duì)象?
這里就只聚焦于 Python 3 的“...”了,不去追溯 Ellipsis 的歷史和現(xiàn)狀。
之所以會(huì)問這個(gè)問題,我的意圖是想知道:它有什么用處,能夠解決什么問題?從而窺探到 Python 語言設(shè)計(jì)中的更多細(xì)節(jié)。
大概有如下的幾種答案:
(1) 擴(kuò)展切片語法
官方文檔中給出了這樣的說明:
Special value used mostly in conjunction with extended slicing syntax for user-defined container data types. 這是個(gè)特殊的值,通常跟擴(kuò)展的切片語法相結(jié)合,用在自定義的數(shù)據(jù)類型容器上。 |
文檔中沒有給出具體實(shí)現(xiàn)的例子,但用它結(jié)合__getitem__() 和 slice() 內(nèi)置函數(shù),可以實(shí)現(xiàn)類似于 [1, ..., 7] 取出 7 個(gè)數(shù)字的切片片段的效果。
由于它主要用在數(shù)據(jù)操作上,可能大部分人很少接觸。聽說 Numpy 把它用在了一些語法糖用法上,如果你在用 Numpy 的話,可以探索一下都有哪些玩法?
(2) 表達(dá)“未完成的代碼”語義
... 可以被用作占位符,也就是我在《Python 為什么要有 pass 語句?》中提到 pass 的作用。前文中對(duì)此已有部分分析。
有人覺得這樣很 cute,這種想法獲得了 Python 之父 Guido 的支持 :
(3) Type Hint 用法
Python 3.5 引入的 Type Hint 是“...”的主要使用場(chǎng)合。
它可以表示不定長(zhǎng)的參數(shù),比如Tuple[int, ...] 表示一個(gè)元組,其元素是 int 類型,但數(shù)量不限。
它還可以表示不確定的變量類型,比如文檔中給出的這個(gè)例子:
from typing import TypeVar, Generic T = TypeVar('T') def fun_1(x: T) -> T: ... # T here def fun_2(x: T) -> T: ... # and here could be different fun_1(1) # This is OK, T is inferred to be int fun_2('a') # This is also OK, now T is str
T 在函數(shù)定義時(shí)無法確定,當(dāng)函數(shù)被調(diào)用時(shí),T 的實(shí)際類型才被確定。
在 .pyi 格式的文件中,... 隨處可見。這是一種存根文件(stub file),主要用于存放 Python 模塊的類型提示信息,給 mypy、pytype 之類的類型檢查工具 以及 IDE 來作靜態(tài)代碼檢查。
(4) 表示無限循環(huán)
最后,我認(rèn)為有一個(gè)非常終極的原因,除了引入“...”來表示,沒有更好的方法。
先看看兩個(gè)例子:
兩個(gè)例子的結(jié)果中都出現(xiàn)了“...”,它表示的是什么東西呢?
對(duì)于列表和字典這樣的容器,如果其內(nèi)部元素是可變對(duì)象的話,則存儲(chǔ)的是對(duì)可變對(duì)象的引用。那么,當(dāng)其內(nèi)部元素又引用容器自身時(shí),就會(huì)遞歸地出現(xiàn)無限循環(huán)引用。
無限循環(huán)是無法窮盡地表示出來的,Python 中用 ... 來表示,比較形象易懂,除了它,恐怕沒有更好的選擇。
最后,我們來總結(jié)一下本文的內(nèi)容:
是 Python 3 中的一個(gè)內(nèi)置常量,它是一個(gè)單例對(duì)象,雖然是 Python 2 中就有的 Ellipsis 的別稱,但它的性質(zhì)已經(jīng)跟舊對(duì)象分道揚(yáng)鑣
可以替代 pass 語句作為占位符使用,但是它作為一個(gè)常量對(duì)象,在占位符語義上并不嚴(yán)謹(jǐn)。很多人已經(jīng)在習(xí)慣上接受它了,不妨一用
在 Python 中不少的使用場(chǎng)景,除了占位符用法,還可以支持?jǐn)U展切片語法、豐富 Type Hint 類型檢查,以及表示容器對(duì)象的無限循環(huán)
對(duì)大多數(shù)人來說,可能并不多見(有人還可能因?yàn)樗且环N符號(hào)特例而排斥它),但它的存在,有些時(shí)候能夠帶來便利。希望本文能讓更多人認(rèn)識(shí)它,那么文章的目的也就達(dá)成了~
到此,關(guān)于“怎么理解Python內(nèi)置對(duì)象”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。