python中内存管理等10个编码习惯

本文涉及的产品
可观测可视化 Grafana 版,10个用户账号 1个月
可观测监控 Prometheus 版,每月50GB免费额度
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 【7月更文挑战第3天】本文涵盖了Python编程中的变量管理、模块导入、命令行参数、内存管理和面向对象设计的10个关键概念。

简介

本文要点涵盖了Python编程中的变量管理、模块导入、命令行参数、内存管理和面向对象设计的一些关键概念:

  1. 避免在函数参数中使用可变数据结构,如列表,
  2. 防止模块循环导入,模块间应明确依赖关系以保护导入。
  3. 命令行参数-u无缓冲输出,-m以模块执行,-x忽略第一行,-X设置特定选项,-从stdin读取。
  4. Python缓存小整数和短字符串is检查对象标识,==检查值相等。
  5. 内存管理基于引用计数和垃圾回收。sys.getrefcount()查看计数,但会因调用本身+1。
  6. 自动垃圾回收可通过gc模块手动触发。阈值可通过gc.get_threshold()查看和设置。
  7. 分代策略:对象按生存时间分代,更老的对象更不易被视为垃圾。垃圾回收针对不同代有不同的触发条件。
  8. 引用环可能导致垃圾回收难题,Python使用额外的引用计数(gc_ref)来检测和回收这类循环引用。
  9. 迭代器、生成器__iter__定义可迭代对象,__next__创建迭代器,yield用于生成器,提供惰性计算。
  10. 抽象方法:使用@abc.abstractmethod声明必须由子类实现的方法,配合__metaclass__ = abc.ABCMeta确保子类覆盖。

mandala曼德罗符号.png

1,不要在函数的参数使用可变数据结构:

注意在函数变量不要使用它

def foo(x=[]):
    x.append(1)
    print(x)

>>>foo()
[1]

>>>foo()
[1,1]

>>>foo()

[1,1,1]

def foo(p=None):
    if p is None:
        p = []
    p.append(1)
    print(p)

foo()
[1]
foo([2,3,4])
[2,3,4,1]

典型数据结构

image.png

2 避免模块的循环导入

我们定义一个老王模块,再定义一个小李模块,相互导入时,将报错

# laowang.py
import xiaoli
count =4
def main():
    wilma.pr('Hello')
if __name__ == '__main__':
    main()

# xiaoli.py
import laowang
def pr(str):
    print(str*fired.count)
if __name__== '__main__':
    pr("Ok")

导入问题,如果在使用其他语言 比如 shell 脚本引用 python代码时,需要将python项目加入 linux环境变量。 <=python2.7

export PYTON_PATH=$PYTHON_PATH:/xxx/xxx/XXXProject

或者编辑 python虚拟环境,添加 setup.py, 然后执行 python install -e .

3 系统输出基础规则

该次执行不缓存sys.stdout,直接输出控制台

@参数 -u unbuffered

执行时带参数m,以Script方式执行py模块

@参数 -m 

跳过py模块第一行,允许使用非unix形式

@参数 -x

实体具体选项(set implementation-specific option)

@参数 -X

程序读取文件内容并执行

file 

程序从stdin 读取

@参数 -

python3 --help # 显示所有参数

dd

4 小的整数 和短小字符,python将缓存以便重复使用

并且is关键字,用于判断两个引用所指对象是否相同

    >>> a = 'gd'
>>> b = 'gd'
>>> a is b
True

== 只判断值是否相同

    a2 = []
b2 = []
>>> a2 is b2
False
>>> b2 == a2
True

5 内存管理对象引用时python基本构成方式

python 内存回收 基于 引用计数 和 分级回收。

赋值的本质 a=1,实际上时修改globals()字典的值,局部变量值的修改locals()的访问和修改

>>> a1
    very good man
>>> globals()['a1'] = 'bad good mm'
>>> globals()

6 引用对象reference count

sys.getrefcount() 查看对象的引用计数,sys.getrefcount()在查看某个引用时将创建一个临时引用,所以引用计数将多1

    >>> c=[1,2,3]

getrefcount(c) #这里c只有一次引用,但是计数时2,因为当前查询有一次临时引用

   2

引用计数的减少和增加

   >>> d=c

getrefcount(c) # 增加引用d,计数3

     3

del d #删除引用d,c的引用计数又重新为2

7 内存管理中垃圾回收机制 garbage collection

垃圾回收时py 独占进行的,大大降低py效率,特定条件下自动启动垃圾回收。

手工回收 gc.collect()

py 运行时分配对象obj allocation 和取消分配对象 deallocation次数被记录,高于垃圾回收阈值,启动垃圾回收

gc.get_threshold()查看该阈值,gc.set)threshold()重新设置该阈值

(700, 10, 10) 700表示启动垃圾回收阈值,10,10表示分别回收的阈值

8 内存管理中垃圾回收分代策略 generation,

基本假设如下。存活时间越久,越不可能在后面程序中变为垃圾。 这样所有对象分为0,1,2三代,所有新建对象都是0代。某一对象经历垃圾回收,仍然存活,那么它就被归入下一代对象。

垃圾回收时,一定扫描0代对象,如果0代经过一定次数垃圾回收,下一次对0代和1代扫描清理,

当1代也经历一次次数垃圾回收,这启动0,1,2所有对象的扫描

以上gc.get_threshold()返回(700,10,10)两个表示每10次0代垃圾回收,将配置1次1代垃圾回收,每10次1代垃圾回收,才有1次2代垃圾回收。

9 内存管理中两个对象相互引用,

相互引用构成引用环 reference cycle,该引用环将给上一节2.4.1的垃圾回收带来困难,

引用环可能构成一些无法使用但引用计数不为0的对象 为了回收该引用环对象,

py复制了每个对象的引用计数为 gc_ref 遍历所有对象,将每个对象引用的对象相应的gc_ref减1,遍历结束后,

gc_ref不为0的对象和这些对象的引用对象,以及继续更新下游引用对象,被爆了,其他对象被回收。

参考 内存管理,函数默认参数,动态类型

10 迭代器的不同

可迭代对象 iter

迭代器 iter + next

生成器 特殊迭代器 yield

          def yd():
        a = 100
        yield a
        yield a*8
        yield 8000
  • 使用抽象方法 (函数)

    对象方法(self.对象方法),类方法(@classmethod),静态方法(@staticmethod)

    抽象方法 需要子类实现的方法 用@abc.abstractmethod以及 metaclass = abc.ABCMeta
    使得任何继承自父类的子类必须覆盖实现抽象方法,否则抛出异常

目录
相关文章
|
5天前
|
算法 Java 程序员
Python内存管理机制深度剖析####
本文将深入浅出地探讨Python中的内存管理机制,特别是其核心组件——垃圾收集器(Garbage Collector, GC)的工作原理。不同于传统的摘要概述,我们将通过一个虚拟的故事线,跟随“内存块”小M的一生,从诞生、使用到最终被回收的过程,来揭示Python是如何处理对象生命周期,确保高效利用系统资源的。 ####
11 1
|
22天前
|
安全 开发者 Python
Python的内存管理pymalloc
Python的内存管理pymalloc
|
26天前
|
安全 开发者 Python
Python的内存管理pymalloc
Python的内存管理pymalloc
|
27天前
|
监控 Java API
Python是如何实现内存管理的
Python是如何实现内存管理的
|
3月前
|
Python
python第三方库-字符串编码工具 chardet 的使用(python3经典编程案例)
这篇文章介绍了如何使用Python的第三方库chardet来检测字符串的编码类型,包括ASCII、GBK、UTF-8和日文编码的检测示例。
141 6
|
3月前
|
Python
Python 中如何指定 open 编码为ANSI
Python 中如何指定 open 编码为ANSI
|
3月前
|
算法 程序员 Python
程序员必看!Python复杂度分析全攻略,让你的算法设计既快又省内存!
在编程领域,Python以简洁的语法和强大的库支持成为众多程序员的首选语言。然而,性能优化仍是挑战。本文将带你深入了解Python算法的复杂度分析,从时间与空间复杂度入手,分享四大最佳实践:选择合适算法、优化实现、利用Python特性减少空间消耗及定期评估调整,助你写出高效且节省内存的代码,轻松应对各种编程挑战。
45 1
|
2月前
|
数据处理 Python
如何优化Python读取大文件的内存占用与性能
如何优化Python读取大文件的内存占用与性能
133 0
|
2月前
|
数据处理 Python
Python读取大文件的“坑“与内存占用检测
Python读取大文件的“坑“与内存占用检测
53 0
|
3月前
|
并行计算 开发者 Python
高效利用Python中的生成器提高内存管理
在处理大量数据或执行复杂计算时,内存管理成为关键问题。Python中的生成器(Generators)提供了一种优雅的解决方案,通过惰性计算和节省内存的方式显著提高程序的效率。本文将探讨生成器的基本概念,实际应用场景,以及如何利用生成器优化内存使用和提高程序性能。