python数据模型与特殊方法

数据模型简介

在python官方文档中对于数据模型是这样介绍的

对象是Python对数据的抽象。Python程序中所有数据都由对象或对象之间的关系表示。在某种意义上,为了和冯诺依曼存储程序计算机模型保持一致,代码和数据一样也是一个对象(冯诺依曼模型中提到,数据和程序都以0,1存储于存储器中)

简单的说,Python中的一切数据要么是对象,要么和对象有关系

如果你带着来自其他面向对象语言的经验进入 Python 的世界,会对 len(object) 而不是 object.len() 写法觉得不适。但是它体现了Python的一种设计思想,也是pythonic的关键所在,而这种思想则体现在Python的数据模型中。

数据模型其实是对 Python 框架的描述,它规范了这门语言自身构建模块的接口,这些模块包括但不限于序列、迭代器、函数、类和上下文管理器。

特殊方法简析

不管在哪种框架下写程序,都会花费大量时间去实现那些会被框架本身调用的方法, Python 也不例外。

Python 解释器碰到特殊的句法时,会使用特殊方法去激活一些基本的对象操作,这些特殊方法的名字以两个下划线开头,以两个下划线结尾(例如 _ getitem_ )。比如 obj[key] 的背后就是 getitem 方法,为了能求得 my_collection[key] 的值,解释器实际上会调用 my_collection.getitem(key)
这些特殊方法名能让你自己的对象实现和支持一下的语言架构,并与之交互

  • 迭代
  • 集合类
  • 属性访问
  • 运算符重载
  • 函数和方法的调用
  • 对象的创建和销毁
  • 字符串表示形式和格式化
  • 管理上下文(即with块)

魔术方法(magic method)是特殊方法的昵称。特殊方法也叫双下方法(dunder method)。

代码示例

接下来通过一个简单的例子来展示如何实现_getitem__len_这两个特殊方法,通过这个例子我们也能见识到特殊方法的强大

import collections

Card = collections.namedtuple('Card', ['rank', 'suit'])

class FrenchDeck:
    ranks = [str(n) for n in range(2, 11)] + list('JQKA')
    suits = 'spades diamonds clubs hearts'.split()

    def __init__(self):
        self._cards = [Card(rank, suit) for suit in self.suits
                                        for rank in self.ranks]

    def __len__(self):
        return len(self._cards)

    def __getitem__(self, position):
        return self._cards[position]

这段代码是一副扑克牌的原型,在这个自定义类中,有三个我们写的特殊方法,通过这几个方法,我们的自定义类就可以在使用的时候像Python的内置类型一样。 我们把这段代码保存为frenchdeck.py文件,然后通过命令行窗口进入该文件所在目录,这里用的是Python3,Python2应该也可以使用。

进入Python shell后如下:

Python 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 16:02:32) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from frenchdeck import *
>>> deck = FrenchDeck()
>>> len(deck)
>>> deck[0]
Card(rank='2', suit='spades')
>>> deck[-1]
Card(rank='A', suit='hearts')
>>>

通过上面的这个例子,我们可以看到,当我们在使用len(deck)和deck[0]时,Python的解释器实际上分别调用了我们在自定义类中的_len__getitem_这两个方法。

然后,假如我们现在要在这一副“扑克牌”中,随机的抽取出一张牌,我们要怎么做呢?自己在写一个方法吗?这在Python中是不用的,Python 已经内置了从一个序列中随机选出一个元素的函数 random.choice,我们直接把它用在这一摞纸牌实例上就好(解释器代码接上面):

>>> from random import choice 
>>> choice(deck)
Card(rank='3', suit='hearts') 
>>> choice(deck)
Card(rank='K', suit='spades') 
>>> choice(deck)
Card(rank='2', suit='clubs')

通过上面的两个例子,我们已经可以体会到通过实现特殊方法来利用 Python 数据模型的两个好处:

1.作为你的类的用户,他们不必去记住标准操作的各式名称(“怎么得到元素的总数?是 .size() 还是 .length() 还是别的什么?”)。

2.可以更加方便地利用 Python 的标准库,比如 random.choice 函数,从而不用重新发明轮子。

同时,我们也能了解到,这些特殊方法的调用,通常都是隐式的,首先明确一点,特殊方法的存在是为了被Python解释器调用的,你自己并不需要调用它们。也就是说没有 my_object._len_() 这种写法,而应该使用 len(my_object)。在执行 len(my_object) 的时候,如果 my_object 是一个自定义类的对象,那么 Python 会自己去调用其中由你实现的 _len_ 方法。
通过内置的函数(例如 len、iter、str,等等)来使用特殊方法是最好的选择。这些内置函数不仅会调用特殊方法,通常还提供额外的好处,而且对于内置的类来说,它们的速度更快。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据结构与算法(Python) 一、引入概念 1-01算法引入 1-02 时间复杂度与大O表示法 1-03-最坏时间复杂度与计算规则 1-04-常见时间复杂度与大小关系 1-05-代码执行时间测量模块 1-06-Python列表类型不同操作的时间效率 1-07-Python列表与字典操作的时间复杂度 1-08-数据结构引入 二、顺序表 2-01 内存、类型本质、连续存储 recv 2-02 基本顺序表与元素外围顺序表 recv 2-03 顺序表的一体式结构与分离式结构 recv 2-04 顺序表数据区替换与扩充 recv 三、栈 3-01 栈与队列的概念 3-02 栈的实现 3-03 队列与双端队列的实现 四、链表 4-01 链表的提出 4-02 单链表的ADT模型 4-03 Python中变量标识的本质 4-04 单链表及结点的定义代码 4-05 单链表的判空、长度、遍历与尾部添加结点的代码实现 4-06 单链表尾部添加和在指定位置添加 4-07 单链表查找和删除元素 4-08 单链表与顺序表的对比 4-09 单向循环链表遍历和求长度 4-10 单向循环链表添加元素 4-11 单向循环链表删除元素 4-12 单向循环链表删除元素复习及链表扩展 4-13 双向链表及添加元素 4-14 双向链表删除元素 五、排序与搜索 5-01 排序算法的稳定性 5-02 冒泡排序及实现 5-03 选择排序算法及实现 5-04 插入算法 5-05 插入排序 5-06 插入排序2 5-07 希尔排序 5-08 希尔排序实现 5-09 快速排序 5-10 快速排序实现1 (1) 5-10 快速排序实现1 5-11 快速排序实现2 5-12 归并排序 5-13 归并排序 代码执行流程 5-14 归并排序时间复杂度及排序算法复杂度对比 5-15 二分查找 5-16 二分查找时间复杂度 六、树和树的算法 6-01 树的概念 6-02 二叉树的概念 6-03 二叉树的广度优先遍历 6-04 二叉树的实现 6-05 二叉树的先序、中序、后序遍历 6-06 二叉树由遍历确定一棵树 ———————————————— 版权声明:本文为CSDN博主「dwf1354046363」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/dwf1354046363/article/details/119832814

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值