Python面向对象编程基础——类、实例对象与内存空间

推荐b站资源:一鼓作气拿下Python的拦路虎:面向对象------苑昊老师

首次学习/快速回顾两相宜

此处仅作为个人学习笔记,仅总结自己认为的重点。


类、实例对象与内存空间

一、当使用定义好的类创建实例时,内存空间发生了什么变化?

如图所示,我们在代码中已经定义好了Dog类以及alex和peiqi两个Dog类下的实例。对应代码如下:

python 复制代码
# 一般而言类名命名建议首字母大写,函数/方法名建议小写。都不能以字母开头。
class Dog:
    # 定义属性
    legs_num = 4
    has_hair = True
    has_tail = True
    
    # 定义方法
    def bark(self):
        print("狂吠")
    def bite(self):
        print("咬人")
    def fetch(self):
        print("叼物品")

那么,当使用如下代码创建alex和peiqi两个实例时,

python 复制代码
alex = Dog()
peiqi = Dog()

内存空间变为这两个实例对象开辟了两块独立的内存空间,由于现在仅仅完成创建实例对象的动作,所以此时的实例对象空间里还什么都没有。

可以使用id()查看这两个实例的内存地址是两个随机的不同的地址。

此时变量名就分别代表这两块空间的起始地址,也就是id()的返回值。


二、当调用某个属性或方法时内存空间的访问顺序是?

刚刚只进行了实例对象创建,如果现在执行:

python 复制代码
print(alex.legs_num)
print(peiqi.legs_num)

那么,首先将会在alex这个对象实例内存空间里查找是否存在legs_num这个属性。因为现在alex的内存空间还是空白的,所以没找到,继而去类内存空间里找该属性,结果找到并返回4。(对于实例对象peiqi也是一样的)

如果使用代码:

python 复制代码
print(id(alex.legs_num))
print(id(peiqi.legs_num))
print(id(Dog.legs_num))

会发现这两个属性分别所对应的内存地址是一样的,其实就是Dog类属性legs_num所对应的内存地址。

对于类属性 (如 legs_num),多个实例访问时确实共享同一个内存地址。

但对于方法(如 bark),每个实例访问时会生成一个临时的绑定方法对象,它们的 id() 可能因内存复用而偶然相同,但本质上是不同的对象。

真正共享的是类中的函数定义(可通过 alex.bark.__func__ 访问)。

所以使用:

python 复制代码
print(id(alex.bark))
print(id(peiqi.bark))
print(id(Dog.bark))

所得到的三个地址应该是不一样的,特别是print(id(alex.bark))和print(id(peiqi.bark)),打印出来应该是两个绑定方法实例的内存地址。但在实际运行中,得到的地址可能偶然相同。

现在我们为alex这个实例对象添加一个属性:

python 复制代码
alex.legs_num =  5

那么alex实例对象的内存空间便多了这个属性,同时不影响Dog类原来的属性,也不影响peiqi这个实例对象的属性。但是如果再次执行:

python 复制代码
print(alex.legs_num)

就会返回5,而不是4。这是因为计算机会先查找alex实例对象的内存空间,发现了legs_num = 5这一属性,就直接返回5。

如果此时执行:

python 复制代码
print(peiqi.legs_num)

那么计算机还是先搜寻peiqi这一实例对象的内存空间,发现没有legs_num这一属性后,再搜索Dog类内存空间里的内容,发现对应的属性赋值为4,则返回4。

从这个例子至少能得出:对于类和实例对象而言,无论调用某个属性或者方法,内存的搜索顺序永远都是:

实例对象自己的内存空间 → 类的内存空间

相关推荐
春日见4 分钟前
5分钟入门强化学习之动态规划算法与实现
大数据·人工智能·python·算法·机器学习·计算机视觉
bug和崩溃我都要9 分钟前
Qt 封装 libmpv 全功能视频播放器开发指南
开发语言·qt·音视频
郝学胜-神的一滴15 分钟前
Qt 高级开发 018:复刻经典登录界面布局与窗口美化全解析
开发语言·c++·qt·程序人生·用户界面
郝亚军21 分钟前
IEEE 754 单精度浮点的SEM表示
开发语言·c++·算法
zhangjw3428 分钟前
第15篇:Java多线程零基础入门,进程线程、线程创建方式、线程生命周期、线程安全彻底吃透
java·开发语言·面试
蝈理塘(/_\)大怨种29 分钟前
类和对象 (上)
java·开发语言
DeniuHe36 分钟前
sklearn 中所有交叉验证数据集划分方式完整总结
人工智能·python·sklearn
DeniuHe39 分钟前
sklearn中不同交叉验证方法的场景适配
人工智能·python·sklearn
小新1101 小时前
qt creator 将qInfo的输出日志写入日志文档,方便查看
开发语言·qt
隐于花海,等待花开1 小时前
16.Python 常用第三方库概览 深度解析
python