说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
在 Python 中,一切皆是对象。编程将现实问题归为一类,抽象为对象,为对象赋于一些通用的信息结构,通用的操作方法、能力,帮助我们解决同类型的问题。本页我们将深入理解在 Python 中对象的设计理念,如何利用对象将现实生活中的事物进行抽象,用编程来解决这些问题。
对象(Object ) 是一个抽象的概念。由于编程是对现实世界的映射,通过技术与现实的对应关系,利用技术来解决现实世界的问题。
在业务层面,对象可代表一切事物,可以理解成一个实际物体(物件),一个事情等,无论这个事物是现实中存在的还是想像中的。
到技术层面,可以对象=确定内存空间+存储在这块内存空间中的值。这一点其实和java有些相似。就对对象和引用这两个概念做了很清晰的区分。Java中,对象是分配在堆上的,存储真正的数据,而引用是在堆栈中开辟的内存空间用于引用某一个对象。抛开java中引用的概念不谈,两种语言对于对象这个概念的理解,我认为还是可以等价的,都是数据+内存空间感觉。Python中,对象才有类型,不同的对象可以拥有不同类型的数据。
Python 中,一切皆对象。对象是分配的一块内存,有足够的空间去表示它们所代表的值。在这个内存空间中,拥有特定的值,支持特定类型的相关操作。
每个对象由标识(identity)、类型(type)、值(value)组成。它们是:
id(obj)
可以返回对象的标识。type(obj)
获得对象的所属类型。print(obj)
可以直接打印值。对象中含有标准的头部信息:类型标识符。标识对象类型,表示对象存储的数据的类型。
类型可以限制对象的取值范围和可执行的操作。使用内置函数type(obj)返回对象所属类型。
每一个对象都有两个标准的头部信息:
引用计数器的目的是为了提高内容效率,Python 设计了垃圾回收机制,将不用的对象清除,当变量的引用计数器为0,自动清理。当然会有一些例外,较小整数型对象有缓存机制。
在 Python 中,变量也称为对象的引用,因为变量存储的就是对象的地址(在 C 实现中就是内存地址),变量通过地址引用了对象,对变量名的操作就是对对象的操作。
变量位于栈(stack)内存,对象位于堆(Heap)内存。变量没有类型,那么就意味着它可以随意指向任何对象。
引用的名称就是标识符,也就是我们经常说的变量名,变量名的命名规则可以参考教程的变量内容。
在 Python 内部,变量只是一个名字,保存指向实际对象的指针,进而与其绑定。 变量赋值只拷贝指针,并不拷贝指针背后的对象。
Python 在堆中分配了独立的小对象缓存区,即小于512 字节的不可变对象,因此内存地址不变:
其他的即使值相同内存也不同,如 浮点数、可变类型(如列表、元组)。
列表和字典这种可变对象当为匿名对象是会向外暴露一个内存地址,不论里面的内容怎么变,该地址不变,如 id([1,2,3]) == id([4,5,6])
为 True。
注:需要在 Python 命令行模式下执行,在如 PyCharm 中进行执行可能会有些许不同,因为 PyCharm 等编辑器自带对变量和对象的一种“优化管理”,不是真正的 Python 的内存管理效果。
对象之间的比较操作有 is
和 ==
操作,它们是通过标识符(变量名)来做这两个操作的。它们的区别是:
is
:对比对象。两个变量是否都引用了同一个对象==
:对比值。对象所存储的数据的值是否相等这些显而易见的东西,很多人应该不以为然,但是一些因语言内部优化的小细节,可能会打破你之前的认识。
In [12]: a = 3
In [13]: b = 3
In [14]: a == b
Out[14]: True
In [15]: a is b
Out[15]: True
按照我们之前所讲的,a 和 b 两个变量应该是引用了两个不同的对象,但是这两个对象内存中的值都是 3。但是,a is b 得到的结果却是 True。原因有如下两点:
Python 对象的大致的一个分类:
图示:
也许 Python 对象系统中最重要的结构之一就是定义新类型的结构: PyTypeObject 结构。 类型对象可以使用任何 PyObject_*
或 PyType_*
函数来处理,但不能提供大多数 Python 应用程序所感兴趣的内容。 这些对象是对象行为的基础,所以它们对解释器本身或任何实现新类型的扩展模块都非常重要。
与大多数标准类型相比,类型对象相当大。这么大的原因是每个类型对象存储了大量的值,大部分是 C 函数指针,每个指针实现了类型功能的一小部分。
变量不需要显示声明类型。根据变量引用的对象,Python 解释器自动确定数据类型。
一般而言,在编译期就确定变量类型的是静态类型语言,在运行期才确定变量类型的则是动态类型语言。
Python 每个对象都有数据类型,只支持该类型支持的操作。
在强类型语言中,变量其实都是有具体的类型来限制的,规定一个类型的变量只能被赋值与该类型相同或兼容的值。但是在 Python 中,显然变量的自由度更大。其次,之前学过体系结构的同学都应该了解,指针的内存空间大小是与类型无关的,其内存空间只是保存了所指向数据的内存地址。之所以说指针也有类型,是因为在计算偏移量的时候,确实需要类型相关的信息。所以,从深层次的含以上来理解,Python 中的变量与强类型语言中的指针非常相似。
Python 在运行时可以防止类型错误,并且很少进行隐式类型转换,没有使用静态类型检查。编译器不检查或强制执行类型约束规则。术语 duck typing 现在被用来描述这个群体中的语言所使用的动态类型范例。
要注意的是,不能认为强类型等于“完全无隐式类型转换”或“只要没有xxx隐式类型转换”。
按强弱类型维度的划分,可以归纳出:
对象与其他概念的关系:
Python 的内置 object() 函数返回一个空对象,不能向该对象添加新属性或方法。这个对象是所有类的基础,它拥有所有类默认的内置属性和方法。
详情可查看教程:object()。
更新时间:2022-05-23 08:34:36 标签:python 对象 object