容易被忽略的Python内置类型


Posted in Python onSeptember 03, 2020

Python中的内置类型是我们开发中最常见的,很多人都能熟练的使用它们。

然而有一些内置类型确实不那么常见的,或者说往往会被我们忽略,所以这次的主题就是带领大家重新认识这些“不同寻常”的内置类型。

(注意:本文基于python3,不会包含任何python2相关内容)

frozenset

不可变集合(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本身又是什么呢?

答案揭晓:

>>> range
<class 'range'>

是的,range是个class!所以当我们使用for i in range(1, 10)这样的代码时,实际上我们遍历了一个range对象,而range也实现了可迭代对象需要的__iter__魔法方法,所以它自身是可迭代对象:

>>> range.__iter__
<slot wrapper '__iter__' of 'range' objects>

因此,range既不返回迭代器,也不返回其他可迭代对象,而是返回的自己。

bytearray

`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还提供了fromhexhex方便将数据以16进制的形式输入输出:

>>> array.hex()
'e6b58be8af95e794a8e4be8b62'
>>> bytearray().fromhex('e6b58be8af95e794a8e4be8b62').decode('utf8')
'测试用例b'

memoryview

`memoryview`提供了直接访问对象内存的机制,只要目标对象支持[buffer protocol](https://docs.python.org/3/c-api/buffer.html#bufferobjects),例如`bytes`和`bytearray`。
memoryview有个称为“元素”的概念,也就是对象规定的最小的内存单元,比如bytesbytearray的最小内存单元就是一个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')

dict-views

准确的说,这不是一种类型,而是一种概念。然而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对象是相当有用的。

The Ellipsis Object (...)

`...`不是一个类型,不过算是一个内置对象。
它没什么特殊的含义,仅表示省略,通常被用在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内置类型的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
在Linux下调试Python代码的各种方法
Apr 17 Python
Python实现快速排序和插入排序算法及自定义排序的示例
Feb 16 Python
Python用list或dict字段模式读取文件的方法
Jan 10 Python
Python中使用支持向量机(SVM)算法
Dec 26 Python
Python爬虫抓取代理IP并检验可用性的实例
May 07 Python
python openpyxl使用方法详解
Jul 18 Python
浅谈Pycharm最有必要改的几个默认设置项
Feb 14 Python
Python编程快速上手——正则表达式查找功能案例分析
Feb 28 Python
PyTorch加载自己的数据集实例详解
Mar 18 Python
python+selenium+Chrome options参数的使用
Mar 18 Python
使用python实现学生信息管理系统
Feb 25 Python
python可视化分析绘制带趋势线的散点图和边缘直方图
Jun 25 Python
python类共享变量操作
Sep 03 #Python
Python pip install之SSL异常处理操作
Sep 03 #Python
详解python tkinter 图片插入问题
Sep 03 #Python
解决PyCharm IDE环境下,执行unittest不生成测试报告的问题
Sep 03 #Python
PyTorch中Tensor的数据类型和运算的使用
Sep 03 #Python
python开发入门——set的使用
Sep 03 #Python
使用anaconda安装pytorch的实现步骤
Sep 03 #Python
You might like
使用PHP 5.0创建图形的巧妙方法
2010/10/12 PHP
PHP学习之输出字符串(echo,print,printf,print_r和var_dump)
2011/04/17 PHP
PHP中文件缓存转内存缓存的方法
2011/12/06 PHP
ajax返回值中有回车换行、空格的解决方法分享
2013/10/24 PHP
css动画效果之animation的常用样式
2021/03/09 HTML / CSS
Javascript 陷阱 window全局对象
2008/11/26 Javascript
javascript replace()正则替换实现代码
2010/02/26 Javascript
在JQuery dialog里的服务器控件 事件失效问题
2010/12/08 Javascript
js图片向右一张张滚动效果实例代码
2013/11/23 Javascript
js正则表达exec与match的区别说明
2014/01/29 Javascript
处理文本部分内容的TextRange对象应用实例
2014/07/29 Javascript
jquery实用技巧之输入框提示语句
2016/07/28 Javascript
Bootstrap按钮功能之查询按钮和重置按钮
2016/10/26 Javascript
Javascript 正则表达式校验数字的简单实例
2016/11/02 Javascript
正则 js分转元带千分符号详解
2017/03/08 Javascript
原生js 封装get ,post, delete 请求的实例
2017/08/11 Javascript
关于vue v-for 循环问题(一行显示四个,每一行的最右边那个计算属性)
2018/09/04 Javascript
基于vue-cli 路由 实现类似tab切换效果(vue 2.0)
2019/05/08 Javascript
基于jQuery实现可编辑的表格
2019/12/11 jQuery
[03:39]2015国际邀请赛主赛事首日精彩回顾
2015/08/05 DOTA
Python设计模式之单例模式实例
2014/04/26 Python
Matplotlib 生成不同大小的subplots实例
2018/05/25 Python
Python中is和==的区别详解
2018/11/15 Python
python中对数据进行各种排序的方法
2019/07/02 Python
django 自定义filter 判断if var in list的例子
2019/08/20 Python
Python udp网络程序实现发送、接收数据功能示例
2019/12/09 Python
keras自定义回调函数查看训练的loss和accuracy方式
2020/05/23 Python
Python读取ini配置文件传参的简单示例
2021/01/05 Python
澳大利亚冲浪和时尚服装网上购物:SurfStitch
2017/07/29 全球购物
莫斯科制造商的廉价皮大衣:Fursk
2020/06/09 全球购物
交通专业个人自荐信格式
2013/09/23 职场文书
财务会计专业推荐信
2013/11/30 职场文书
成功经营餐厅的创业计划书范文
2013/12/26 职场文书
政协会议宣传标语
2014/10/09 职场文书
Python-typing: 类型标注与支持 Any类型详解
2021/05/10 Python
深入理解Vue的数据响应式
2021/05/15 Vue.js