您好,登錄后才能下訂單哦!
Python中的內置類型是我們開發中最常見的,很多人都能熟練的使用它們。
然而有一些內置類型確實不那么常見的,或者說往往會被我們忽略,所以這次的主題就是帶領大家重新認識這些“不同尋常”的內置類型。
(注意:本文基于python3,不會包含任何python2相關內容)
不可變集合(frozenset)與普通的set一樣,只不過它的元素是不可變的,因此諸如`add`,`remove`,`update`等可以添加/刪除/改變集合內元素的方法是不存在的,換句話說一旦frozenset建立后你將不再可能更改集合內的元素。其他的方法與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
的使用,但并不清楚range
到底是什么。返回迭代器?返回一個可迭代對象?range本身又是什么呢?
答案揭曉:
>>> range <class 'range'>
是的,range
是個class!所以當我們使用for i in range(1, 10)
這樣的代碼時,實際上我們遍歷了一個range
對象,而range
也實現了可迭代對象需要的__iter__
魔法方法,所以它自身是可迭代對象:
>>> range.__iter__ <slot wrapper '__iter__' of 'range' objects>
因此,range
既不返回迭代器,也不返回其他可迭代對象,而是返回的自己。
`bytearray`一般情況下并不常見,它主要為了可以實現原地修改bytes對象而出現,因為bytes和str一樣是不可變對象,例如這樣是非法的: ```python >>> b = '測試用例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 ``` 而當我們把bytes的內容復制給`bytearray`時就可以進行原地修改了: ```python >>> array = bytearray(b) >>> array[-1] = 98 >>> array.decode('utf8') 測試用例b ``` `bytearray`對象沒有字面常量,因此只能通過構造函數創建,它有著和bytes一樣的方法,只是可變以及多了一些序列對象的特性。如果要創建一個`bytearray`可以有如下的幾種方法: - `bytearray()`返回一個空的`bytearray`對象 - `bytearray(10)`創建一個長度為10且內容被0填充的`bytearray` - `bytearray(iterable)`會將可迭代對象的內容轉換成bytes然后存入對象中 - `bytearray(b'Hi!')`將已有的二進制數據復制進對象
另外bytearray
還提供了fromhex
和hex
方便將數據以16進制的形式輸入輸出:
>>> array.hex() 'e6b58be8af95e794a8e4be8b62' >>> bytearray().fromhex('e6b58be8af95e794a8e4be8b62').decode('utf8') '測試用例b'
`memoryview`提供了直接訪問對象內存的機制,只要目標對象支持[buffer protocol](https://docs.python.org/3/c-api/buffer.html#bufferobjects),例如`bytes`和`bytearray`。
memoryview
有個稱為“元素”的概念,也就是對象規定的最小的內存單元,比如bytes
和bytearray
的最小內存單元就是一個byte,具體取決于對象的實現。
len(view)
通常等于len(view.tolist())
,也就是等于view的“元素”數量。如果view.ndim == 0
,那么整個view的內存會被視作一個整體,len會返回1,如果view.ndim == 1
那么就正常返回“元素”的個數。view.itemsize會返回單個“元素”的大小。單位是byte。
view.readonly
表示當前的memoryview
是否是只讀的,例如bytes對象的view就是只讀的,view.readonly
的值為True
。是否只讀取決于被引用的對象是否可變以及對buffer protocol的實現。
對于使用完畢的memoryview應該盡快調用其release()方法釋放資源,而且部分對象在被view引用時會自動進行一些限制,比如bytearray
會禁止調整大小,及時釋放view是資源可以解除這些限制。
結合示例可以更清晰地了解這些特性:
>>> data = bytearray(b'abcefg') >>> v = memoryview(data) >>> v.readonly False >>> v[0] = ord(b'z') >>> data bytearray(b'zbcefg') >>> v[1:4] = b'123' >>> data bytearray(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' >>> data bytearray(b'z1spam')
準確的說,這不是一種類型,而是一種概念。然而typing里仍然將其視為一種類型,所以也就羅列在此了。
概念:返回自dict.keys()
,dict.values()
和dict.items()
的對象被稱作dict-views。
對于views對象,可以使用len,成員檢測,它本身也是可迭代對象:
>>> 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開始)以及views動態反應了key/value的插入和刪除以及修改,因此在某些場景下views對象是相當有用的。
`...`不是一個類型,不過算是一個內置對象。
它沒什么特殊的含義,僅表示省略,通常被用在type hints中:
>>> ... Ellipsis >>> from typing import Callable >>> func: Callable[..., None] = lambda x,y:print(x*y)
func是一個沒有返回值的函數,參數列表沒有做任何限制。
你也可以寫成Ellipsis
,兩者是等價的,不過顯然是...這種形式更簡單明了。
以上就是這些容易被忽略和遺忘的內置類型,如有錯誤和疏漏歡迎指出。
https://docs.python.org/3/library/stdtypes.html
https://docs.python.org/3/c-api/buffer.html#bufferobjects
以上就是容易被忽略的Python內置類型的詳細內容,更多關于Python內置類型的資料請關注億速云其它相關文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。