Python学习之路20-数据模型(python数据模块)
off999 2024-10-04 19:00 19 浏览 0 评论
本篇是Python进阶篇的开始。本篇主要是对Python特殊方法的概述。
1. 前言
数据模型其实是对Python框架的描述,它规范了这门语言自身构件模块的接口,这些模块包括但不限于序列、迭代器、函数、类和上下文管理器。不管在哪种框架下写程序,都会花费大量时间去实现那些会被框架本身调用的方法,Python也不例外。Python解释器碰到特殊句法时,会使用特殊方法去激活一些基本的对象操作,这些特殊方法的名字以两个下划线开头,以两个下划线结尾(所以特殊方法也叫双下方法 dunder method),这些特殊方法名能让自己编写的对象实现和支持以下的语言构架,并与之交互:
迭代、集合类、属性访问、运算符重载、函数和方法的调用、对象的创建和销毁、字符串表示形式和格式化、管理上下文(即with块)。
下面通过一些例子来介绍常用的特殊方法。
2. Python风格纸牌
首先介绍两个特殊方法 __getitem__ 和 __len__ 这两个特殊方法。以下代码创建了一个纸牌类:
namedtuple,即命名元组,类似于C/C++中的struct,定义如下:
collections.namedtuple(typename, field_names, verbose=False, rename=False)
第一个参数是元组名;第二个是该元组中含的属性名;第三个参数表示在构建该命名元组之前先打印出该命名元组的结构,如果在控制台输入第3行代码,并置verbose为True的话,会输出该命名元组的内部结构,实际上它是一个继承自tuple的类,由于输出过长,请大家自行实验;如果该命名元组的元素名中有Python关键字,则需要置第四个参数为True,这些与关键字重名的元素名会被特殊处理。
用命名元组创建一个不带方法的对象十分简单:
由于FrenchDeck实现了 __getitem__ 方法,所以可以像操作List或Tuple一样操作FrenchDeck,比如随机访问,切片:
由于实现了该方法,FrenchDeck还是个可迭代对象,即可以用for循环对其访问(也可以反向访问reversed):
迭代通常是隐式的,譬如说一个集合类型没有实现__contains__方法,那么in运算符就会按顺序做一次迭代搜索(调用__getitem__),于是in运算符可以用在FrenchDeck上:
如果对上述deck变量调用sorted函数,Python将按ASCII码进行排序,但这并不是扑克牌的正确排序,所以下面我们自定义排序方法:
此时输出的结果就是先按点数排序,再按花色排序。
3. 如何使用特殊方法
需要明确一点,特殊方法的存在是为了给Python解释器调用到,作为程序员并不需要调用他们,也即是说,没有my_object.__len__()这种写法,而应该是len(my_object)。说到__len__方法,如果是Python内置类型,CPython会抄个近路,该方法实际上会直接返回PyVarObject里的ob_size属性,而PyVarObject是表示内存中长度可变的内痔对象的C语言结构体。
很多时候特殊方法的调用是隐式的,比如for i in x: 这个语句,背后其实用的是iter(x),而这个函数的背后则是x.__iter__()方法,当然前提是这个方法在x中被实现(如果没被实现则会调用__getitem__方法)。
直接调用这个值比调用一个方法快很多。直接调用特殊方法的频率应该远远低于你去实现它们的次数。
通过内置的函数(例如len,iter,str等)来使用特殊方法是最好的选择。这些内置函数不仅会调用特殊方法,通常还提供额外的好处,而且对于内置的类来说,它们的速度更快。
还有一点值得注意:不要想当然地随意添加特殊方法,比如__foo__之类的,因为虽然现在这个名字没有被Python内部使用,以后就不一定了。
3.1 自定义向量Vector
使用5个特殊方法实现Vector的字符串输出,取绝对值(如果是复数则是取模),返回布尔值,加法和数乘等运算:
Python有一个内置函数叫做repr。该函数通过特殊方法__repr__来得到一个对象的字符串表示形式,如果没有该特殊方法,当我们在控制台打印一个向量对象时,得到的字符串可能是<Vector object at 0x10e00070>:
__repr__ 与 __str__的区别与联系:前者方便我们调试和记录日志,后者则是给终端用户看的。后者是在str()函数被使用,或者是在print函数打印一个对象的时候才被调用,它返回的字符串对终端用户友好。如果只想实现这两个特殊方法中的一个,__repr__ 是更好的选择,因为如果一个对象没有 __str__ 函数,Python又需要调用它时,解释器会用 __repr__ 代替。
上述Vector类实现了 __bool__ 方法,它可用于需要布尔值的上下文中(if, while, and, or, not等)。默认情况下,我们自己定义的类的实例总被认为是True,除非重写了这个类的 __bool__ 或 __len__ 方法。bool(x)的背后是调用 x.__bool__();如果不存在 __bool__ 方法,那么bool(x)会尝试调用 x.__len__(),如果该方法返回0,则bool返回False,否则返回True。
3.2 为什么len不是普通方法
“实用胜于纯粹”(Python之禅里的一句话)。len之所以不是一个普通方法,是为了让Python自带的数据结构可以走后门,abs也是同理。但多亏了它是特殊方法,我们也可以把len用于自定义数据类型。这种处理方式在保持内置类型的效率和保证语言的一致性之间找到了一个平衡点,也印证了“Python之禅”中的另一句话:“不能让特例特殊到考试破坏既定规则”。
4. 总结
通过实现特殊方法,自定义数据类型可以表现得跟内置类型一样,从而让我们写出更具Python风格(Pythonic)的代码。后面的内容将围绕更多的特殊方法展开。
相关推荐
- python爬取电子课本,送给居家上课的孩子们
-
在这个全民抗疫的日子,中小学生们也开启了居家上网课的生活。很多没借到书的孩子,不得不在网上看电子课本,有的电子课本是老师发的网络链接,每次打开网页去看,既费流量,也不方便。今天我们就利用python的...
- 高效办公!Python 批量生成PDF文档是如何做到的?
-
前言:日常办公中,经常会使用PDF文档,难免需要对PDF文档进行编辑,有时候PDF文档中的大部分内容都是一样的,只是发送对象不同。这种模板套用的场景下,使用Python进行自动化就尤为方便,用最短的时...
- 如何用Python将PDF完整的转成Word?
-
PDF文件完整的转为Word,转换后格式排版不会乱,图片等信息完整显示不丢失。这个很简单,有很多方法都可以实现。方法一:Python利用Python将PDF文件转换为Word,有许多库可以帮你实现这一...
- 使用Python拆分、合并PDF(python合并多个pdf)
-
知识点使用Python操作PDF!主要内容有:1、PDF拆分;2、PDF合并。在工作中,难免会和PDF打交道,所以掌握一点处理PDF的技能非常有必要,本文将介绍几个常用的功能。PDF拆分很多时候,获取...
- 10分钟实现PDF转Word神器!看DeepSeek如何用Python解放打工人
-
开篇痛点每个被PDF折磨过的职场人都懂——领导发来的扫描件要修改,手动抄到Word需要2小时;网上下载的报告想复制数据,却变成乱码…今天我们用Python+DeepSeek,10分钟打造一个智能转换工...
- 《Python知识手册》,高清全彩pdf版开放下载
-
Python编程还不懂?今天我要把我参与编写的这套《Python知识手册》免费分享出来,看完文末有惊喜哦。...
- 利用python进行数据分析,PDF文档给你答案
-
本书详细介绍利用Python进行操作、处理、清洗和规整数据等方面的具体细节和基本要点。虽然本书的标题是“数据分析”,重点却是Python编程、库,以及用于数据分析的工具。兄弟,毫无套路!PDF版无偿获...
- OCRmypdf:一款可以让扫描PDF文件变得可搜索、可复制!
-
简介在日常工作中,我们经常会接触到各种PDF文件,其中不少是扫描版文档。处理这些扫描PDF时,尽管内容看似完整,但往往无法直接复制或搜索其中的文本。尤其是在需要对大量文档进行文本分析、存档或后期编辑时...
- 高效的OCR处理工具!让扫描PDF文件变得可搜索、可复制!
-
在工作中,我们常常遇到各种各样的PDF文件,其中不乏一些扫描版的文档。而在处理扫描的PDF文件时,虽然文件内容看似完整,但你却无法复制、搜索其中的文本。特别是对大量文档需要进行文本分析、存档、或者...
- 三步教你用Elasticsearch+PyMuPDF实现PDF大文件秒搜!
-
面对100页以上的大型PDF文件时,阅读和搜索往往效率低下。传统关系型数据库在处理此类数据时容易遇到性能瓶颈,而Elasticsearch凭借其强大的全文检索和分布式架构,成为理想解决方案。通过...
- 用 Python 去除 PDF 水印,你学会吗?
-
今天介绍下用Python去除PDF(图片)的水印。思路很简单,代码也很简洁。首先来考虑Python如何去除图片的水印,然后再将思路复用到PDF上面。这张图片是前几天整理《数据结构和算法...
- 扫描PDF档案效率提升300%!OCRmyPDF:告别无法搜索的PDF噩梦,这款26K Star的开源神器让文本识别轻松上手!
-
要在PDF中搜索某个关键词,结果发现啥也找不到?这种情况大多数人都遇到过吧,特别是处理扫描文档或图片PDF时。就在前几天,我还在为这事抓狂呢!后来无意中发现了OCRmyPDF这个宝藏项目...简直就...
- Python自动化办公之PDF版本发票识别并提取关键信息教程(上篇)
-
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Python自动化办公发票数据处理的问题,一起来看看吧。二、实现过程这个问题在实际工作中还是非常常见的,实用性和通用性都比...
- PDF解锁神器:用PyMuPDF与pdfplumber告别手动提取
-
前言大家好,今天咱们来聊聊如何用Python中的PyMuPDF和pdfplumber库,轻松提取PDF文件里的文本和元数据。你是否曾经在处理一个复杂的PDF文件时,感到信息难以触及,提取过程让人抓狂?...
- 《Python知识手册》,高清pdf免费获取
-
今天我要把我参与编写的这套《Python知识手册》免费分享出来,真正弘扬Python开源精神!手册的部分页面如下:获取方式:...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- python爬取电子课本,送给居家上课的孩子们
- 高效办公!Python 批量生成PDF文档是如何做到的?
- 如何用Python将PDF完整的转成Word?
- 使用Python拆分、合并PDF(python合并多个pdf)
- 10分钟实现PDF转Word神器!看DeepSeek如何用Python解放打工人
- 《Python知识手册》,高清全彩pdf版开放下载
- 利用python进行数据分析,PDF文档给你答案
- OCRmypdf:一款可以让扫描PDF文件变得可搜索、可复制!
- 高效的OCR处理工具!让扫描PDF文件变得可搜索、可复制!
- 三步教你用Elasticsearch+PyMuPDF实现PDF大文件秒搜!
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python自定义函数 (53)
- python进度条 (67)
- python吧 (67)
- python字典遍历 (54)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python串口编程 (60)
- python读取文件夹下所有文件 (59)
- java调用python脚本 (56)
- python操作mysql数据库 (66)
- python字典增加键值对 (53)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python人脸识别 (54)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)