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。

相关文章
|
16天前
|
机器学习/深度学习 JSON Java
Java调用Python的5种实用方案:从简单到进阶的全场景解析
在机器学习与大数据融合背景下,Java与Python协同开发成为企业常见需求。本文通过真实案例解析5种主流调用方案,涵盖脚本调用到微服务架构,助力开发者根据业务场景选择最优方案,提升开发效率与系统性能。
157 0
|
10天前
|
存储 大数据 Unix
Python生成器 vs 迭代器:从内存到代码的深度解析
在Python中,处理大数据或无限序列时,迭代器与生成器可避免内存溢出。迭代器通过`__iter__`和`__next__`手动实现,控制灵活;生成器用`yield`自动实现,代码简洁、内存高效。生成器适合大文件读取、惰性计算等场景,是性能优化的关键工具。
128 2
|
5月前
|
存储 缓存 Java
【高薪程序员必看】万字长文拆解Java并发编程!(5):深入理解JMM:Java内存模型的三大特性与volatile底层原理
JMM,Java Memory Model,Java内存模型,定义了主内存,工作内存,确保Java在不同平台上的正确运行主内存Main Memory:所有线程共享的内存区域,所有的变量都存储在主存中工作内存Working Memory:每个线程拥有自己的工作内存,用于保存变量的副本.线程执行过程中先将主内存中的变量读到工作内存中,对变量进行操作之后再将变量写入主内存,jvm概念说明主内存所有线程共享的内存区域,存储原始变量(堆内存中的对象实例和静态变量)工作内存。
161 0
|
2月前
|
传感器 数据采集 监控
Python生成器与迭代器:从内存优化到协程调度的深度实践
简介:本文深入解析Python迭代器与生成器的原理及应用,涵盖内存优化技巧、底层协议实现、生成器通信机制及异步编程场景。通过实例讲解如何高效处理大文件、构建数据流水线,并对比不同迭代方式的性能特点,助你编写低内存、高效率的Python代码。
119 0
|
2月前
|
数据采集 数据可视化 API
驱动业务决策:基于Python的App用户行为分析与可视化方案
驱动业务决策:基于Python的App用户行为分析与可视化方案
|
3月前
|
JavaScript Java Go
Go、Node.js、Python、PHP、Java五种语言的直播推流RTMP协议技术实施方案和思路-优雅草卓伊凡
Go、Node.js、Python、PHP、Java五种语言的直播推流RTMP协议技术实施方案和思路-优雅草卓伊凡
177 0
|
4月前
|
数据采集 数据可视化 JavaScript
用Python采集CBC新闻:如何借助海外代理IP构建稳定采集方案
本文介绍了如何利用Python技术栈结合海外代理IP采集加拿大CBC新闻数据。内容涵盖使用海外代理IP的必要性、青果代理IP的优势、实战爬取流程、数据清洗与可视化分析方法,以及高效构建大规模新闻采集方案的建议。适用于需要获取国际政治经济动态信息的商业决策、市场预测及学术研究场景。
|
5月前
|
数据可视化 Linux iOS开发
Python测量CPU和内存使用率
这些示例帮助您了解如何在Python中测量CPU和内存使用率。根据需要,可以进一步完善这些示例,例如可视化结果或限制程序在特定范围内的资源占用。
188 22
|
6月前
|
数据采集 自然语言处理 JavaScript
Playwright多语言生态:跨Python/Java/.NET的统一采集方案
随着数据采集需求的增加,传统爬虫工具如Selenium、Jsoup等因语言割裂、JS渲染困难及代理兼容性差等问题,难以满足现代网站抓取需求。微软推出的Playwright框架,凭借多语言支持(Python/Java/.NET/Node.js)、统一API接口和优异的JS兼容性,解决了跨语言协作、动态页面解析和身份伪装等痛点。其性能优于Selenium与Puppeteer,在学术数据库(如Scopus)抓取中表现出色。行业应用广泛,涵盖高校科研、大型数据公司及AI初创团队,助力构建高效稳定的爬虫系统。
292 2
Playwright多语言生态:跨Python/Java/.NET的统一采集方案
|
6月前
|
Python
解决Python报错:DataFrame对象没有concat属性的多种方法(解决方案汇总)
总的来说,解决“DataFrame对象没有concat属性”的错误的关键是理解concat函数应该如何正确使用,以及Pandas库提供了哪些其他的数据连接方法。希望这些方法能帮助你解决问题。记住,编程就像是解谜游戏,每一个错误都是一个谜题,解决它们需要耐心和细心。
279 15

推荐镜像

更多