python成员属性特性

python成员属性特性

python成员属性内存特性

这篇博客主要分享一下python成员属性的内存特性,也就是python底层节约内存的优化方案

成员属性的默认值

假设我们在定义成员属性是给他一个默认值,那么所有的实例中的成员属性都是指向同一块内存,而不是每个实例创建不同的内存空间去存储成员属性,下面的代码实例

复制代码
class MemoryCharacter(object):
    def __init__(self):
        self.aData: str = "123"


m1 = MemoryCharacter();
m2 = MemoryCharacter();

print(id(m1.aData), id(m2.aData));

m1.aData和m2.aData的内存地址都是一样的

复制代码
2536375837360 2536375837360

python成员属性的内存会不会导致数据出问题

上面的代码实例可以看出,两个实例的成员属性的指向都是一样的,那么会不会出现这样的情况,就是修改m1.aData的值会不会改变m2.aData的值

复制代码
class MemoryCharacter(object):
    def __init__(self):
        self.aData: str = "123"


m1 = MemoryCharacter();
m2 = MemoryCharacter();
m1.aData = "333";
print(m1.aData, m2.aData);
print(id(m1.aData), id(m2.aData))

这里打印m1.aData和m2.aData的值已经不一样了

复制代码
333 123

内存地址也会不一样了

复制代码
2736447097712 2736449239600

这样的结果就是python底层做的内存处理,因为 = 来赋值就是创建一个全新的内存空间来存储的,所以每次改动都是创建一个全新的地址来存储

除了基本类型以外其他数据类型没有这个特性

这种特性只有是基本数据类型才会有,比如list、dict等数据类型是不会存在的,会每个实例单独创建一个内存空间来存储

复制代码
class MemoryCharacter3:
    def __init__(self):
        self.cData: [int] = [3];


m5 = MemoryCharacter3();
m6 = MemoryCharacter3();
print(id(m5.cData), id(m6.cData))

1918241582528 1918241584832

在构造函数中给成员属性赋值内存会是怎么样的处理

复制代码
class MemoryCharacter2:
    def __init__(self, data: str):
        self.data = data;


m3 = MemoryCharacter2("aaa");
m4 = MemoryCharacter2("bbb");

print(id(m3.data), id(m4.data));

如上面这个代码,两个实例的实例属性的内存地址都是不一样的

复制代码
1664226701040 1664226701232

上面这个又是什么原因导致的呢?我又在构造函数中打印传入的参数的地址

复制代码
class MemoryCharacter2:
    def __init__(self, data: str):
        print(id(data))
        self.data = data;


m3 = MemoryCharacter2("aaa");
m4 = MemoryCharacter2("bbb");

print(id(m3.data), id(m4.data));

发现传入的参数地址就是最后这个实例成员属性的地址,由此得知,函数参数的传递是地址传递,而不是值传递。

因为上面的是使用基本数据类型来传递才会这样,那使用list这种不是基本数据类型的会有什么结果

复制代码
class MemoryCharacter2:
    def __init__(self, data: str,cData:[int]):
        print(id(cData))
        self.cData = cData;
        self.data = data;


m3 = MemoryCharacter2("aaa",[123]);
m4 = MemoryCharacter2("bbb",[444]);

print(id(m3.cData), id(m4.cData));

打印结果为

复制代码
1644995262272
1644995262400
1644995262272 1644995262400

由此得知,python的参数是使用地址传递的,才导致成员属性地址不一样

python成员属性特性原因是什么呢?

假设有一个类,这个类的一个成员属性是一个固定值,但是又想每个实例中单独使用,不跟所有人共享,如果这个类的实例有几万个,那么他这个成员属性就会存在几万个,有因为是固定值,那么这种行为就极其浪费内存空间,由此原因,python底层就创建一个固定空间,共全部实例使用,这样既不会浪费空间,又不影响功能

python这种处理有什么坏处呢?

假设你实例要使用到内存相关的处理,那么python成员属性的特性会导致你有各种奇奇怪怪的bug。

相关推荐
无敌最俊朗@9 分钟前
C++-Qt-音视频-基础问题01
开发语言·c++
kyle~12 分钟前
C++---万能指针 void* (不绑定具体数据类型,能指向任意类型的内存地址)
开发语言·c++
MediaTea21 分钟前
Python 第三方库:TensorFlow(深度学习框架)
开发语言·人工智能·python·深度学习·tensorflow
vortex532 分钟前
Bash Glob 通配符详细指南:从 POSIX 标准到高级用法
开发语言·bash
KdanMin36 分钟前
Android MediaCodec 硬编解码实战:从Camera预览到H264流与回环渲染
android·开发语言
Joker-Tong42 分钟前
大模型数据洞察能力方法调研
人工智能·python·agent
B站计算机毕业设计之家1 小时前
基于Python+Django+双协同过滤豆瓣电影推荐系统 协同过滤推荐算法 爬虫 大数据毕业设计(源码+文档)✅
大数据·爬虫·python·机器学习·数据分析·django·推荐算法
逻极1 小时前
Webhook 全解析:事件驱动时代的实时集成核心技术
python·web
程序员三藏1 小时前
一文了解UI自动化测试
自动化测试·软件测试·python·selenium·测试工具·职场和发展·测试用例
极客代码1 小时前
第七篇:深度学习SLAM——端到端的革命--从深度特征到神经辐射场的建图新范式
人工智能·python·深度学习·计算机视觉·slam·回环检测·地图构建