【Python】Python学习笔记(五)对象

对象和类型

Python中将一切都视为对象。在语法的很多细节上通过上层封装掩盖了底层逻辑,故需要仔细理解Python中底层的操作机制,才能避免在一些基本问题上出错。

对象

对象就是内存中的一块存放着数据的区域,拥有唯一的标识符。

在Python中,任意元素都是对象,而每个对象都有标识符、类型和值等属性。
使用id()函数可以以查看任意元素的标识符。
在这里插入图片描述
如上述变量n的id和5的id就是相同的,通常情况下是内存地址。

二值交换

在cpp中,我们如何交换两个变量的值?
通常做法是需要借助第三个临时变量:

int a,b,t;
t = a;
a = b;
b = t;

而在Python中,似乎拥有一种更加简单,无需通过临时变量的方法即可交换:

a, b= b, a;

从内存角度来看,这两种语言在交换时是存在区别的。

cpp
有三个内存区域,我们可以想象成三个抽屉,这三个抽屉分别贴上了a,b,t的标签(变量名)。
在交换a,b元素的时候,先得a抽屉里的内容复制一份到t中;
再把a抽屉里面的内容从b中复制一份,覆盖掉a抽屉原本的内容;
最后将t中存放a原本内容的副本,复制到b中,将b原本的内容覆盖。
完成这些步骤后,a中放着b之前元素的复制,b中放着a之前元素的复制。如此一来,就完成了二值交换的过程。在内存中,原本a元素所在的地址中的内容确确实实变成了b的值,b同理。
Python
仍然可以将内存中的两个区域想象成两个抽屉,抽屉上贴着两个标签a,b。Python的交换方法非常简单,其直接把这两个抽屉的标签“撕了下来”,将原本的a抽屉贴上了b标签,b抽屉贴上了a标签。
这样一来,再去查询b抽屉的时候,实际上就是之前的a抽屉,其中的内容也是之前a抽屉的值,现在的a抽屉同样如此。这样一来,看上去就完成了a与b的交换,而实际上在内存中,原本a和b地址所存放的数值并没有交换,只是这些内存地址的名字发生了变化。

在cpp中,变量名和内存区域是绑定的,而在Python中,内存区域和值是绑定的,这是两者最大的区别。
通俗来说:若把cpp的内存区域看成一个抽屉,那么这个抽屉上面的标签是“撕不下来”的,但是里面的内容是可以被更改的。而Python恰恰相反,这个抽屉和里面的内容是绑定的,但是它的标签却可以随意更改。

在Python中,任何一个内存区域和其中的值永远被视为一体,叫做对象。

每个对象拥有唯一的标识符(通常是内存地址)。

每一个对象可以拥有数个“名字”,所谓的变量也只不过是某个对象的一个“名字罢了”。

也就是存在多个变量指向同一个对象(指向内存当中同一个抽屉)。

在这里插入图片描述
如上图,看似存在abcdf五个变量,倘若这五个变量的值都是1,那么他们实际上都指向同一块存放着“1”这个值的内存区域,故他们的标识符都相等。即实际上这五个变量名只不过是“1”这个对象的马甲而已。

数据和内存区域密不可分,被叫做对象,这一点和对象名与内存区域密不可分,而数据可变的cpp完全不同。

cpp的情况:

在这里插入图片描述
在cpp中,虽然这五个变量都是5,但是5只是这些“抽屉中的值”,这5个变量实实在在的和五个抽屉所绑定。

从以上的例子,可以总结出Python对象的几个特点和性质:

  • 变量是对象的引用,它只是关联到对象的一个名字。
  • 在对变量进行赋值操作时,不会复制对象的值(即不会改变内存中某一个区域里面存放的内容),只会改变引用对象。
  • 在Python中,一切皆为对象。对象占一定的存储空间,并拥有标识符、类型和值等属性。

变量看似会变,实际上只是对于内存中不同不变数据的引用而已。

可变类型和不可变类型

上述所举的数字属于不可变类型,即一旦在内存中生成某个存放某一数值的内存区域后,这一内存区域的值就不能再发生改变。这一点是由Python内存区域和值的紧密结合性而定。

Python中也存在一些值可以发生改变的类型。

  • 可变类型:列表、字典、集合。
  • 不可变类型:数字、字符串、元组。

身份运算符

x is y :如果x和y引用了同一个对象,则生成True,否则生成False。
x is not y:如果x和y不是同一个对象则生成True,否则生成False。

通常情况下会使用身份运算符比较可变类型,因为可变类型存在值相等但是标识符不同的情况(即存在内存中不同区域存放了相同值的情况)

赋值语句

前面的例子可以看出,Python中由于是将内存区域与值进行绑定,故对于不可变类型不存在修改内存区域内容的问题,那么赋值语句实际上并没有同cpp一般,改变了某一个变量所引用的内存区域中的数据内容。

可以总结出赋值语句的一些特性:

  • 等号右边的值没有复制到等号左边。
  • 等号左边的变量名绑定到等号右边的对象(使变量可盈引用对象)。
  • 等号左边的变量名如果是第一次使用,则新生成一个变量。

del语句

del语句可以解除一个名称与对象的引用,如果该名称是对象的唯一引用,那么程序就会释放该对象的内存。

个人心得

在初学c和cpp的时候,最头疼的无疑是数据类型,要仔细的分辨各种数据类型的数据范围,也要弄清楚语言在内存当中具体是如何操作的。数据类型的那张大表已经成了任何c/cpp教材第一章或者第二章的老主顾。
但Python显然通过对象和引用关系自动封装了“数据类型”一说,在创建任何一个变量的时候,Python会通过引用的方式自动给你连接合适的数据类型,对于数据的修改也变成了“自动引用”新的对象,就不存在所谓的数据类型的大问题。
当然,作为程序的使用者,我们仍然需要知道Python中对于各种数据类型其的一些细节,但是无疑,花开两朵,各表一枝,Python与cpp在底层对于内存数据的使用上决定了其的学习方式和关注点的不同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

两米长弦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值