Python数据模型与Python对象模型
数据模型==对象模型
Python官方文档说法是“Python数据模型”,大多数Python书籍作者说法是“Python对象模型”,它们是一个意思,表示“计算机编程语言中对象的属性”。这句话有点抽象,只要知道对象是Python对数据的抽象,在Python中万物皆对象就可以了。
官方文档严谨说法,Python程序中的所有数据都是用对象或对象之间的关系来表示的。
对象三要素
对象有三个要素:编号(identity)、类型(type)、值(value)。
identity
编号就是对象的内存地址,从创建后就不会改变。is
运算符用来比较2个对象的编号。id()
函数返回对象编号的整数表示。
identity也可以翻译为身份,对象身份。
type
类型决定了可以对对象做哪些操作,也定义了对象的可能值,比如int
和bool
类型的值就不一样。type()
函数返回对象类型。很多人会误以为Python是弱类型语言,其实Python是强类型语言,这个误解的真实原因是,Python不需要编译,不需要提前知道变量的类型,在运行时才检查类型,这应该叫做动态语言。
JavaScript是弱类型语言,在Python中
1+"2"
会运行失败,在JavaScript中能运行成功。
类型在创建后也不会改变,虽然可以进行类型转换,但转换实际会产生新对象:
a = 1
print(id(a))
print(id(str(a)))
print(id(a))
结果为:
140715000207008
2136059506160
140715000207008
value
对象三要素中唯一能改变的就只有值了。官网有一句正确的废话:允许改变值的对象是mutable
(可变的),不允许改变值的对象是immutable
(不可变的)。它的意义在于当不可变对象的值是对可变对象的引用时,该如何判断对象的可变性?结论是不可变对象仍然是不可变的,因为这个引用是不能变的,但是我们通常会认为这个不可变对象的值是可变的,尤其是对象容器。对象类型也会决定是否可变,比如numbers
、strings
、tuples
是不可变的,dictionaries
、lists
是可变的。
对象容器
有些对象包含了对其他对象的引用,这叫做containers
对象容器,比如tuples
、lists
、dictionaries
。大多数情况下,我们说容器的值,说的是引用的对象的值,而不是引用编号。但讨论容器可变性时,则仅仅是指容器直接包含的引用编号。比如tuple
是不可变的,如果它包含了对一个可变对象的引用后,当该可变对象改变时容器的值也会改变。
对象回收
对象不会被显式销毁,但是它们会被当做垃圾回收,只要不存在对象引用,这就是Python垃圾回收机制!垃圾回收机制比较复杂,比如循环引用,实际上已经没有使用了,但是还存在引用等,涉及到算法规则,等写完Python进阶,在写Python原理时做进一步研究。
Python垃圾回收机制不是银弹,不能解决所有问题,所以在引用外部资源,比如打开文件后,我们需要注意显式close,防止资源始终占用内存,无法释放,造成内存泄漏。close除了手动调用close()
方法外,也可以使用with
来自动close。
使用
try...except
可能会让对象继续存活。
类型决定一切
对象的类型几乎决定了对象的一切行为,甚至是对象编号,比如对于不可变类型:
a = 1
b = 1
a
和b
可能会指向同一个值为1
的对象,也可能会指向两个不同的值为1
的对象,这取决于具体实现。
但是对于可变类型:
c = []
d = []
c
和d
一定会指向两个不同的单独的空列表。
注意
c = d = []
则是将同一个对象赋值给c
和d
。
小结
Python数据模型就是常说的对象模型,万物皆对象,有编号、类型、值三个要素。了解了对象模型后,Python另一个重要概念即将浮出水面,它就是数据结构。
参考资料:
《流畅的Python》
最新文章
- java字节流与字符流的区别
- Task示例,多线程
- java基础九[网络与线程](阅读Head First Java记录)
- HDU 4044 GeoDefense(动态规划)
- nginx 负载均衡服务器的双机搞可用
- The Wonderful Wizard of Oz-绿野仙踪-(音频+文本)-英文版本
- Cisco笔试——2014年
- Elasticsearch 2.3 (ELK)Geo_point绘图、日志Date时间获取实例
- ajax详细讲解和封装包括HTTP状态码
- 个人作业2——NBA 2k18案例分析
- Linux下实现普通用户免密码登录【超详细】
- Zookeeper介绍 Zookeeper搭建 Zookeeper集群搭建
- maven 编译出错Fatal error compiling: 无效的目标发行版: 1.8 ->; [Help 1] 解决办法
- Linux集群时间同步方法
- odoo开发笔记--开启后台日志记录
- 终止java线程的2种方法
- ansible教程
- PARAMETERS 指令
- redis缓存存在的隐患及其解决方案
- canvas :原生javascript编写动态时钟
热门文章
- mini-web框架-元类-总结(5.4.1)
- luabind 使用
- 用Python从头开始构建神经网络
- (十二)、file--判断文件类型命令
- CentOS安装TensorFlow
- OneBlog开源博客-详细介绍如何实现freemarker自定义标签
- 7.24,《C Primer Plus》复习第十五章第二小题
- .NET 云原生架构师训练营(模块二 基础巩固 MongoDB 聚合)--学习笔记
- slice,splice,split,unshift的用法
- Windows搭建SkyWalking8.3环境进行JAVA应用性能监控及入门示例(使用Mysql持久化)