今天,谈谈python中的数据模型,当然你可以不了解这些东西,照样可以写出漂亮的python代码,但是“知其然知其所以然”是我的作风,总是不明白python的一些机制,心里很不爽。结合python的doc和一篇文章,差不多明白了python的哲理。
我觉得有必要将python中的文档的一些重要语句拿出来。
Objects are Python’s abstraction for data. All data in a Python program is represented by objects or by relations between objects.
Every object has an identity, a type and a value.
为什么我这里要强调这里的对象,有对象以为着有一些属性(函数也罢,变量也罢都是属性)与之关联,你操作一个对象,其实就是在和这些属性打交道。
在这里,我集中在python中的类,去弄明白python中的类究竟是怎么完成其功能的.
A class has a namespace implemented by a dictionary object. Class attribute references are translated to lookups in this dictionary.
这句话很重要,一个类有其自己的namespace(命名空间),而且这个命名空间的实现本质上是一个字典。换句话说,你对一个类的操作其实就是在对这个“特殊”的字典进行操作,那么怎么去区分类的实例和类呢,其实在python中,类的实例也有一个字典,去记录该实例的属性。
- class T(object):
- age = 21
-
- t = T()
- t.name = "ilovebaiyang"
-
- print "dir(T):", dir(T)
- print "dir(t):", dir(t)
这个打印的结果是:
- dir(T): ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age']
-
- dir(t): ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name']
其中有些属性是从object上继承来的,比如__doc__, __setattr__,__dict__等等,其中值得注意的是自定义属性,age和name,他们分别存在于类T中和类T的实例t中,那么为什么在dir(t)中出现了age的属性呢,原因是从它的类上复制过来的,而且如果我们打印他们的id,其实他们的id是一样的。在这里,我们出现了一个疑问,前面提到的命名空间的字典就是dir()函数产生的字典么,看上去貌似是,因为它的确记录了该对象的所有属性,其实这个是错误的,原因我们就要回到dir函数上了,它的作用是罗列出当前对象的所有属性,包括父类的。其实,前面提到的命名空间是的__dict__成员,所有与该对象对应的属性全部放在这个字典里。
我们打印出来看看
- T.__dict__: {'__dict__': , '__module__': '__main__', '__weakref__': , 'age': 21, '__doc__': None}
-
- t.__dict__: {'name': 'ilovebaiyang'}
这一下才会和我们想象的一样,name属性只存在实例中。
接下来是属性的查找:
如果我们要打印t.age,怎么搜索
- 1.先查找该实例的__dict__,如果有,返回,否则进行第二步
- 2.查找类的__dict__,如果有返回,没有的话,继续查找该类的父类,直到基类,如果还没有,抛出异常。
当然,其实python中的查找还做了很多其他事,特别是一些隐含的调用,如果我们重写这些隐含的调用,就可以写出符合我们的数据。
看下面的例子:
- class T(object):
- def __setattr__(self, name, value):
- print "__setattr__ called "
- object.__setattr__(self, name, value)
-
- def __getattr__(self, name):
- print "__getattr__ called "
-
- def __getattribute__(self, name):
- print "__getattribute__ called"
- return object.__getattribute__(self, name)
-
- t = T()
- t.name = "baiyang"
- print "t", t.name
- t.baiyang
结果:
- __setattr__ called
- t __getattribute__ called
- baiyang
- __getattribute__ called
- __getattr__ called
分析以上的结果,当t.name被执行时,先调用了__setattr__函数;当print “t”, t.name时,调用了__getattribute__函数;当t.baiyang时,调用了__getattr__函数,因为t没有baiyang这个属性,故调用这个函数。
其实简单的想一下,会明白,我们在操作namespace这个字典时,我们都会隐式的调用相应的函数,这些函数可以用来进行数据的验证。
总结一下,在操作类的实例的属性时,我们需要关注一下函数:
object.__setattr__(self, name, value)
object.__getattr__(self, name)
object.__delattr__(self, name)
object.__getattribute__(self, name)
其中你对任何对象的属性访问时,都会隐式的调用__getattribute__方法,比如你调用t.__dict__,其实你执行了t.__getattribute__(“__dict__”)函数。
神奇的python,把字典用的如此灵活,由此可以看出字典在python的地位是何其的重要。
在这里,我们或许想到了怎么不去隐式的调用这些函数,对,我们可以直接去操作类或者类实例的__dict__。看看下面的例子:
- class T(object):
- age = 21
- def __setattr__(self, name, value):
- print "__setattr__ called "
- object.__setattr__(self, name, value)
-
- def __getattr__(self, name):
- print "__getattr__ called "
-
- def __getattribute__(self, name):
- print "__getattribute__ called"
- return object.__getattribute__(self, name)
-
- t = T()
- t.__dict__["name"] = "baiyang"
- print "t.__dict__: ", t.__dict__["name"]
- print "t.age: ", t.age
- print "t.__dict__['age']: ", t.__dict__["age"]
结果
- __getattribute__ called
- t.__dict__: __getattribute__ called
- baiyang
- t.age: __getattribute__ called
- 21
- t.__dict__['age']: __getattribute__ called
-
- Traceback (most recent call last):
- File "C:\Users\Administrator\Desktop\lab\SogouW\Freq\test.py", line 18, in
- print "t.__dict__['age']: ", t.__dict__["age"]
- KeyError: 'age'
我们来分析一下:
1.t__dict__["name"] = “baiyang”其中调用了__getattribute__函数,因为__dict__本身也是一个属性的,所以它必须会执行的;但是你会发现此时__setattr__并没有执行,达到了我们想要的效果;
2.print “t.age: “, t.age
print “t.__dict__['age']: “, t.__dict__["age"]这才是重点,第二条语句抛出了KeyError的异常,再一次证明了age只是存在于类的namespace中。
最后,我们与python中的descriptor进行比较:
可以看这篇文章,我就不细讲了。
主要一点就是descriptor对应的函数是
object.__get__(self, instance, owner)
object.__set__(self, instance, value)
object.__delete__(self, instance)
可以看出少了attr这个词,也以为着我们必须将他们区分看。descriptor是对类的实例进行的操作,内建函数property()就是通过这个方式实现的。看了此文,是不是对python的工作机制更加了解了呢?
好了,在这里提几个问吧,你可以去网上搜到答案
- 如何创建immutable的数据,我之前的一篇文章已经给出了答案。
- 如何创建singleton模式的数据
如果你明白了上面的文章,你就会明白,不论你想写出什么样的数据,只要去重写python中一些内在的函数即可。
-----------------打造高质量的文章 更多关注 把酒泯恩仇---------------
为了打造高质量的文章,请 推荐 一个吧。。。。谢谢了,我会写更多的好文章的。
请关注sina微博:http://weibo.com/baiyang26
把酒泯恩仇官方博客:http://www.ibaiyang.org 【推荐用google reader订阅】
把酒泯恩仇官方豆瓣:http://www.douban.com/people/baiyang26/
分享到:
相关推荐
神经网络模型一般用来做分类,回归预测模型不常见,本文基于一个用来分类的BP神经网络,对它进行修改,实现了一个回 归模型,用来做室内定位。模型主要变化是去掉了第三层的非线性转换,或者说把非线性激活函数...
python预测模型python预测模型python预测模型python预测模型python预测模型python预测模型python预测模型python预测模型python预测模型python预测模型python预测模型python预测模型python预测模型python预测模型...
python基于ARIMA时间序列的销量预测模型全部数据.zipARIMA模型提供了基于时间序列理论,对数据进行平稳化处理(AR和MA过程)、模型定阶(自动差分过程)、参数估计,建立模型,并对模型进行检验。 在Python中...
基于python的新冠肺炎疫情数据可视化及建模预测.zip基于python的新冠肺炎疫情数据可视化及建模预测.zip基于python的新冠肺炎疫情数据可视化及建模预测.zip基于python的新冠肺炎疫情数据可视化及建模预测.zip基于...
将 Excel 分析转换为 Python 和 pandas 数据模型.zip 将 Excel 分析转换为 Python 和 pandas 数据模型.zip 将 Excel 分析转换为 Python 和 pandas 数据模型.zip 将 Excel 分析转换为 Python 和 pandas 数据模型.zip ...
Python源码集锦-心血管预测模型数据+代码
基于python的GPT2中文摘要生成模型代码实现
# 通过顶点和面生成gltf和glb模型文件 Python源码 gltflib示例 1. 使用Python gltflib库读写gltf和glb模型文件 2. 通过顶点(vertex)坐标列表,以及顶点组成面(face)的列表,生成模型文件。 3. 解决了模型中定义...
基于python建立二元回归线性模型对数据进行分析并预测。原理是分别建立被解释变量Y与6个解释变量X1、X2、X3、X4、X5和X6的一元线性回归模型;根据每一个一元线性回归模型的检验结果,选择其中一个模型为基本模型,...
利用Python构建Wiki中文语料词向量模型试验
在时间序列预测问题中,建立LSTM模型,采用python语言代码实现
数据模型。 本次研究所得的分类模型,可以帮助被招聘者在浏览网站招聘信息时预测薪 资待遇水平,有效的评估招聘内容是否合适,以及对招聘岗位提供的薪资待遇是 否感到满意,进而有效的提高求职者在寻求招聘岗位吋的...
使用Python编写的小程序,可用于基于模型的协同过滤电影评分预测模型
Python获取lunwen信息,包含数据爬取、数据分析、数据可视化代码,直接输入关键词即可获取相关数据信息
python 学习笔记——线性回归预测模型.pdf python 学习笔记——线性回归预测模型.pdf python 学习笔记——线性回归预测模型.pdf python 学习笔记——线性回归预测模型.pdf python 学习笔记——线性回归预测模型.pdf ...
资料说明:包括数据+代码+文档+代码讲解。 前言 2.项目背景 3.分析流程 4.数据预处理 5.评论分词 6.情感分析与建立模型 7.实际应用
基于python的中文预训练RoBERTa模型
以python构建Fama and French三因子(MKT、SMB、HML),代码从网络整理,可以运行,数据可通过tushare pro下载。
Python实现SVM(源码+数据)