python:对象

对象(object)

  • Python是一门面向对象的语言, 一切皆对象!
    • 程序运行当中,所有的数据都是存储到内存当中然后再运行的!
    • 对象就是内存中专门用来存储指定数据的一块区域
    • 对象实际上就是一个容器,专门用来存储数据
    • 像我们之前学习的数值、字符串、布尔值、None都是对象

对象的结构

每个对象由标识(identity)、类型(type)、值(value)组成。它们是:

  • id(标识)

    • id用来标识对象的唯一性,每一个对象都有唯一的id。 对象的id就相当于人的身份证号一样, 对象一旦创建,则它的id永远不能再改变
    • id是由解析器生成的,在CPython中,id就是对象的内存地址,但是在其他 Python 解释器中可能是别的值。
    • 可以通过id(obj)函数来查看对象的id
      • 其实,编程中很少使用 id() 函数。
      • 标识最常使用 is 运算符检查,而不是直接比较 ID。
    • is 运算符比较两个对象的标识;
      • == 运算符比较两个对象的值(对象中保存的数据),而 is 比较对象的标识。
      • 通常,我们关注的是值,而不是标识,因此 Python 代码中 == 出现的频率比 is 高。
      • 然而,在变量和单例值之间比较时,应该使用 is。目前,最常使用 is 检查变量绑定的值是不是 None:x is None
      • is 运算符比 == 速度快,因为它不能重载,所以 Python 不用寻找并调用特殊方法,而是直接比较两个整数 ID。
      • 而 a == b 是语法糖,等同于 a.__eq__(b)。继承自 object 的 __eq__方法比较两个对象的 ID,结果与 is 一样。但是多数内置类型使用更有意义的方式覆盖了__eq__ 方法,会考虑对象属性的值。
  • type(类型)

    • 类型用来标识当前对象所属的类型。比如:int str float bool 。。。
    • 对象中含有标准的头部信息:类型标识符。标识对象类型,表示对象存储的数据的类型。
    • 类型可以限制对象的取值范围和可执行的操作。使用内置函数type(obj)返回对象所属类型。
    • 每一个对象都有两个标准的头部信息:
      • 类型标识符,去标识对象的(数据)类型;
      • 引用计数器,记录当前对象的引用的数目。
        • 引用计数器的目的是为了提高内容效率,Python 设计了垃圾回收机制,将不用的对象清除,当变量的引用计数器为0,自动清理。
        • 当然会有一些例外,较小整数型对象有缓存机制。
          在这里插入图片描述
  • value(值)

    • 值就是对象中存储的具体的数据
    • 使用 print(obj) 可以直接打印值。
    • 对于有些对象值是可以改变的。 对象分成两大类,可变对象 不可变对象
      在这里插入图片描述
      在这里插入图片描述
a = 10
b = a  #别名

print(a, b)  #10 10
print(b == a) #True
print(b is a) #True
print(id(a), id(b))  #2718681530896 2718681530896

b = 11
print(a, b)  #10 11
print(b == a) #False
print(b is a) #False
print(id(a), id(b))  #2718681530896 2814573347344

变量与对象

  • 对象并没有直接存储到变量中,在Python中变量更像是给对象起了一个别名
  • 变量中存储的不是对象的值,而是对象的id(内存地址),
    • 当我们使用变量时,实际上就是在通过对象id在查找对象
  • 变量中保存的对象,只有在为变量重新赋值时才会改变
    • 在 Python 内部,变量只是一个名字,保存指向实际对象的指针,进而与其绑定。
    • 变量赋值只拷贝指针,并不拷贝指针背后的对象
  • 变量位于栈(stack)内存,对象位于堆(Heap)内存。

在这里插入图片描述

python在堆中分配了独立的小对象缓存区, 即小于512字节的不可变对象, 因此内存地址不变:

  • 小整数对象池:范围为 [-5, 256] 的小整数 int
  • 无空格的小字符串(不包含中文等) str (intern 字符串滞留机制)
  • 布尔值 bool

其他的即使值相同内存也不同,如 浮点数、可变类型(如列表、元组)。
在这里插入图片描述

列表和字典这种可变对象当为匿名对象是会向外暴露一个内存地址,不论里面的内容怎么变,该地址不变,如 id([1,2,3]) == id([4,5,6]) 为 True。

注:需要在 Python 命令行模式下执行,在如 PyCharm 中进行执行可能会有些许不同,因为 PyCharm 等编辑器自带对变量和对象的一种“优化管理”,不是真正的 Python 的内存管理效果。

== != is is not

  • == != :对比值。对象所存储的数据的值是否相等
  • is is not :对比对象。两个变量是否都引用了同一个对象
a = [1,2,3]
b = [1,2,3]
print(a,b)
print(id(a),id(b))
print(a == b)  # a和b的值相等,使用==会返回True
print(a is b)  #  a和b不是同一个对象,内存地址不同,使用is会返回False

这些显而易见的东西,很多人应该不以为然,但是一些因语言内部优化的小细节,可能会打破你之前的认识。

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在底层做了一定的优化, 对于使用过的整数以及字符串都会被缓存起来, 所以上述 b 引用的应该是被缓存过的 3
  • 之所以采用这种优化方式, 是因为python中数字和字符串一经创建都是不可修改的, 所以不会出现因为使用了缓存的对象值造成"脏读"的问题

对象的分类

Python 对象的大致的一个分类:

  • Fundamental 对象: 类型对象
  • Numeric 对象: 数字对象
  • Sequence 对象: 容纳其他对象的序列集合对象
  • Mapping 对象: 类似 C++ 中的 map 的关联对象
  • Internal 对象: Python 虚拟机在运行时内部使用的对象

图示:

在这里插入图片描述

类型对象

也许 Python 对象系统中最重要的结构之一就是定义新类型的结构: PyTypeObject 结构。 类型对象可以使用任何 PyObject_* 或 PyType_* 函数来处理,但不能提供大多数 Python 应用程序所感兴趣的内容。 这些对象是对象行为的基础,所以它们对解释器本身或任何实现新类型的扩展模块都非常重要。

与大多数标准类型相比,类型对象相当大。这么大的原因是每个类型对象存储了大量的值,大部分是 C 函数指针,每个指针实现了类型功能的一小部分。

对象与其他概念的关系:

  • 变量与对象:变量是对对象的引用
  • 类与对象:类就是创建对象的模板,只有创建了类,才能够通过它创建出对象
  • 类型与对象:对象都有类型,相同的类型有相同的属性(特征)和方法(行为)

object()

Python 的内置 object() 函数返回一个空对象,不能向该对象添加新属性或方法。这个对象是所有类的基础,它拥有所有类默认的内置属性和方法。

可变对象

  • 每个对象中都保存了三个数据:
    id(标识)
    type(类型)
    value(值)

  • 列表就是一个可变对象
    a = [1,2,3]

  • a[0] = 10 (改对象)

    • 这个操作是在通过变量去修改对象的值
    • 这种操作不会改变变量所指向的对象
    • 当我们去修改对象时,如果有其他变量也指向了该对象,则修改也会在其他的变量中体现
  • a = [4,5,6] (改变量)

    • 这个操作是在给变量重新赋值
    • 这种操作会改变变量所指向的对象
    • 为一个变量重新赋值时,不会影响其他的变量
  • 一般只有在为变量赋值时才是修改变量,其余的都是修改对象

#  可变对象
 a = [1,2,3]
 print('修改前:', a , id(a))

#  通过索引修改列表
 a[0] = 10
 print('修改后:', a , id(a))

#  为变量重新赋值
 a = [4,5,6]
 print('修改后:', a , id(a))




a = [1,2,3]
b = a
 b[0] = 10
b = [10,2,3]
 print("a",a,id(a))
 print("b",b,id(b))
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值