容易被忽略的Python內(nèi)置類型
Python中的內(nèi)置類型是我們開(kāi)發(fā)中最常見(jiàn)的,很多人都能熟練的使用它們。
然而有一些內(nèi)置類型確實(shí)不那么常見(jiàn)的,或者說(shuō)往往會(huì)被我們忽略,所以這次的主題就是帶領(lǐng)大家重新認(rèn)識(shí)這些“不同尋常”的內(nèi)置類型。
(注意:本文基于python3,不會(huì)包含任何python2相關(guān)內(nèi)容)
frozenset不可變集合(frozenset)與普通的set一樣,只不過(guò)它的元素是不可變的,因此諸如`add`,`remove`,`update`等可以添加/刪除/改變集合內(nèi)元素的方法是不存在的,換句話說(shuō)一旦frozenset建立后你將不再可能更改集合內(nèi)的元素。其他的方法與set一致: ```python >>> frozen = frozenset([1, 1, 2, 3, 4, 5, 6, 6]) frozenset({1, 2, 3, 4, 5, 6}) >>> frozen | {1, 2, 3, 7, 8} frozenset({1, 2, 3, 4, 5, 6, 7, 8}) >>> frozen ^ {1, 2, 3, 7, 8} frozenset({4, 5, 6, 7, 8}) ```
range`range`事實(shí)上相當(dāng)?shù)贸R?jiàn),所以你也許會(huì)奇怪我為什么把它列出來(lái)。其實(shí)原因很簡(jiǎn)單,因?yàn)榇蟛糠秩耸煜ange的使用,但并不清楚range到底是什么。返回迭代器?返回一個(gè)可迭代對(duì)象?range本身又是什么呢?
答案揭曉:
>>> range<class ’range’>
是的,range是個(gè)class!所以當(dāng)我們使用for i in range(1, 10)這樣的代碼時(shí),實(shí)際上我們遍歷了一個(gè)range對(duì)象,而range也實(shí)現(xiàn)了可迭代對(duì)象需要的__iter__魔法方法,所以它自身是可迭代對(duì)象:
>>> range.__iter__<slot wrapper ’__iter__’ of ’range’ objects>
因此,range既不返回迭代器,也不返回其他可迭代對(duì)象,而是返回的自己。
bytearray`bytearray`一般情況下并不常見(jiàn),它主要為了可以實(shí)現(xiàn)原地修改bytes對(duì)象而出現(xiàn),因?yàn)閎ytes和str一樣是不可變對(duì)象,例如這樣是非法的: ```python >>> b = ’測(cè)試用例a’.encode(’utf8’) >>> b[-1] = 98 # change ’a’ -> ’b’ Traceback (most recent call last): File '', line 1, in TypeError: ’bytes’ object does not support item assignment ``` 而當(dāng)我們把bytes的內(nèi)容復(fù)制給`bytearray`時(shí)就可以進(jìn)行原地修改了: ```python >>> array = bytearray(b) >>> array[-1] = 98 >>> array.decode(’utf8’) 測(cè)試用例b ``` `bytearray`對(duì)象沒(méi)有字面常量,因此只能通過(guò)構(gòu)造函數(shù)創(chuàng)建,它有著和bytes一樣的方法,只是可變以及多了一些序列對(duì)象的特性。如果要?jiǎng)?chuàng)建一個(gè)`bytearray`可以有如下的幾種方法: - `bytearray()`返回一個(gè)空的`bytearray`對(duì)象 - `bytearray(10)`創(chuàng)建一個(gè)長(zhǎng)度為10且內(nèi)容被0填充的`bytearray` - `bytearray(iterable)`會(huì)將可迭代對(duì)象的內(nèi)容轉(zhuǎn)換成bytes然后存入對(duì)象中 - `bytearray(b’Hi!’)`將已有的二進(jìn)制數(shù)據(jù)復(fù)制進(jìn)對(duì)象
另外bytearray還提供了fromhex和hex方便將數(shù)據(jù)以16進(jìn)制的形式輸入輸出:
>>> array.hex()’e6b58be8af95e794a8e4be8b62’>>> bytearray().fromhex(’e6b58be8af95e794a8e4be8b62’).decode(’utf8’)’測(cè)試用例b’memoryview
`memoryview`提供了直接訪問(wèn)對(duì)象內(nèi)存的機(jī)制,只要目標(biāo)對(duì)象支持[buffer protocol](https://docs.python.org/3/c-api/buffer.html#bufferobjects),例如`bytes`和`bytearray`。memoryview有個(gè)稱為“元素”的概念,也就是對(duì)象規(guī)定的最小的內(nèi)存單元,比如bytes和bytearray的最小內(nèi)存單元就是一個(gè)byte,具體取決于對(duì)象的實(shí)現(xiàn)。
len(view)通常等于len(view.tolist()),也就是等于view的“元素”數(shù)量。如果view.ndim == 0,那么整個(gè)view的內(nèi)存會(huì)被視作一個(gè)整體,len會(huì)返回1,如果view.ndim == 1那么就正常返回“元素”的個(gè)數(shù)。view.itemsize會(huì)返回單個(gè)“元素”的大小。單位是byte。
view.readonly表示當(dāng)前的memoryview是否是只讀的,例如bytes對(duì)象的view就是只讀的,view.readonly的值為True。是否只讀取決于被引用的對(duì)象是否可變以及對(duì)buffer protocol的實(shí)現(xiàn)。
對(duì)于使用完畢的memoryview應(yīng)該盡快調(diào)用其release()方法釋放資源,而且部分對(duì)象在被view引用時(shí)會(huì)自動(dòng)進(jìn)行一些限制,比如bytearray會(huì)禁止調(diào)整大小,及時(shí)釋放view是資源可以解除這些限制。
結(jié)合示例可以更清晰地了解這些特性:
>>> data = bytearray(b’abcefg’)>>> v = memoryview(data)>>> v.readonlyFalse>>> v[0] = ord(b’z’)>>> databytearray(b’zbcefg’)>>> v[1:4] = b’123’>>> databytearray(b’z123fg’)>>> v[2:3] = b’spam’Traceback (most recent call last): File '<stdin>', line 1, in <module>ValueError: memoryview assignment: lvalue and rvalue have different structures>>> v[2:6] = b’spam’>>> databytearray(b’z1spam’)dict-views
準(zhǔn)確的說(shuō),這不是一種類型,而是一種概念。然而typing里仍然將其視為一種類型,所以也就羅列在此了。概念:返回自dict.keys(),dict.values()和dict.items()的對(duì)象被稱作dict-views。
對(duì)于views對(duì)象,可以使用len,成員檢測(cè),它本身也是可迭代對(duì)象:
>>> dishes = {’eggs’: 2, ’sausage’: 1, ’bacon’: 1, ’spam’: 500}>>> keys = dishes.keys()>>> values = dishes.values()>>> # iteration>>> n = 0>>> for val in values:... n += val>>> print(n)504>>> # keys and values are iterated over in the same order (insertion order)>>> list(keys)[’eggs’, ’sausage’, ’bacon’, ’spam’]>>> list(values)[2, 1, 1, 500]>>> # view objects are dynamic and reflect dict changes>>> del dishes[’eggs’]>>> del dishes[’sausage’]>>> list(keys)[’bacon’, ’spam’]>>> # set operations>>> keys & {’eggs’, ’bacon’, ’salad’}{’bacon’}>>> keys ^ {’sausage’, ’juice’}{’juice’, ’sausage’, ’bacon’, ’spam’}
從例子中可以看出,views保持著元素的插入順序(插入順序的保證從python3.6開(kāi)始)以及views動(dòng)態(tài)反應(yīng)了key/value的插入和刪除以及修改,因此在某些場(chǎng)景下views對(duì)象是相當(dāng)有用的。
The Ellipsis Object (...)`...`不是一個(gè)類型,不過(guò)算是一個(gè)內(nèi)置對(duì)象。它沒(méi)什么特殊的含義,僅表示省略,通常被用在type hints中:
>>> ...Ellipsis>>> from typing import Callable>>> func: Callable[..., None] = lambda x,y:print(x*y)
func是一個(gè)沒(méi)有返回值的函數(shù),參數(shù)列表沒(méi)有做任何限制。
你也可以寫(xiě)成Ellipsis,兩者是等價(jià)的,不過(guò)顯然是...這種形式更簡(jiǎn)單明了。
以上就是這些容易被忽略和遺忘的內(nèi)置類型,如有錯(cuò)誤和疏漏歡迎指出。
參考:https://docs.python.org/3/library/stdtypes.html
https://docs.python.org/3/c-api/buffer.html#bufferobjects
以上就是容易被忽略的Python內(nèi)置類型的詳細(xì)內(nèi)容,更多關(guān)于Python內(nèi)置類型的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. React+umi+typeScript創(chuàng)建項(xiàng)目的過(guò)程2. .Net core 的熱插拔機(jī)制的深入探索及卸載問(wèn)題求救指南3. ASP調(diào)用WebService轉(zhuǎn)化成JSON數(shù)據(jù),附j(luò)son.min.asp4. SharePoint Server 2019新特性介紹5. 三個(gè)不常見(jiàn)的 HTML5 實(shí)用新特性簡(jiǎn)介6. 解決ASP中http狀態(tài)跳轉(zhuǎn)返回錯(cuò)誤頁(yè)的問(wèn)題7. ASP中常用的22個(gè)FSO文件操作函數(shù)整理8. 無(wú)線標(biāo)記語(yǔ)言(WML)基礎(chǔ)之WMLScript 基礎(chǔ)第1/2頁(yè)9. ASP.NET Core 5.0中的Host.CreateDefaultBuilder執(zhí)行過(guò)程解析10. ASP編碼必備的8條原則
