python变量和常量_PYTHON变量与常量,引用与回收

python 变量与常量,赋值指向 与回收

1 变量与常量

变量###

在计算机进程中,变量不仅可以是数字,还可以是任意数据类型。

a = 1

变量a是一个整数。

t_007 = 'T007'

变量t_007是一个字符串。

Answer = True

变量Answer是一个布尔值True。

a = 123 # a是整数

print(a)

a = 'ABC' # a变为字符串

print(a)

变量赋值的意义

方便多次使用

可以修改指向的内容

动态语言与静态语言

和静态语言相比,动态语言更灵活

变量本身类型不固定的语言称之为动态语言 如python。静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错。

Java 静态类型

int a = 123; // a是整数类型变量

a = "ABC"; // 错误:不能把字符串赋给整型变量

变量在计算机内存中的表示

创建的过程 + 指向(引用)的过程

a = ‘hello’时,在内存中创建了一个’ABC’的字符串;

在内存中创建了一个名为a的变量,并把它指向’ABC’。

a = 'hello'

b = a

a = 'XYZ'

print(b)

常量

常量就是不能变的变量。

在Python中,通常用全部大写的变量名表示常量

PI=3.1415...

2 赋值引用与垃圾回收

Python是动态类型的语言,赋值的时候对象和引用分离

即先创建对象后引用

a=1

Python的内置函数id()

身份信息id–内存地址

a = 1

b = 1

print(id(a)) 11246696

print(id(b)) 11246696

即 a,b 是指向同一个对象的两个引用

is 用来判断两个变量的指向是否一致

注意: python 缓存 数字 和 短字符串, 长字符串和其他数据类型 会生成新的对象

# a='apple'

# b='apple'

# print(a is b)

# print(id(a),id(b))

# True

# 5812440 5812440 短字符

# m=1

# n=1

# print(m is n)

# print(id(m),id(n))

# True

# 1486795840 1486795840 数字

# x='very good morning'

# y='very good morning'

# print(x is y)

# print(id(x),id(y))

# False

# 32008784 36101768 长字符

x='very good morning'

y='very good morning'

print(x is y)

False

print(id(x),id(y))

32008784 36101768 其它数据类型

应用计数与垃圾回收

在Python中,每个对象都有存有指向该对象的引用计数(reference count)

from sys import getrefcount

m = [1,2]

print(getrefcount(m)) #2 1+1

n = m

print(getrefcount(n)) # 3 2+1

# 在使用 getrefcount的时候 变量作为参数 传进去,会多一次引用

引用计数是 Python采取了一种相对简单的垃圾回收机制,可以有效的释放内存

引用环—影响垃圾回收

两个对象可能相互引用,从而构成所谓的引用环(reference cycle)

a = []

b = [a]

a.append(b)

减少引用

del关键字

from sys import getrefcount

a = [1, 2, 3]

b = a

print(getrefcount(b))

del a

print(getrefcount(b))

重新赋值定向

a = [1, 2, 3]

b = a

print(getrefcount(b))

a = 1

print(getrefcount(b))

垃圾回收

当某个对象的引用计数降为0时,没有任何引用指向时,该对象就成为要被回收的垃圾了

a = [1, 2, 3]

del a 删除 a后,没有任何引用指向之前建立的[1, 2, 3]。用户不可能通过任何方式接触或者动用这个对象。当垃圾回收启动时,Python扫描到这个引用计数为0的对象,就将它所占据的内存清空。

频繁的垃圾回收降低Python的工作效率

垃圾回收时,Python不能进行其它的任务。频繁的垃圾回收将大大降低Python的工作效率。ython只会在特定条件下,自动启动垃圾回收

垃圾回收启动的阈值条件

当Python运行时,会记录其中分配对象(object allocation)和取消分配对象(object deallocation)的次数。当两者的差值高于某个阈值时,垃圾回收才会启动。

gc模块的get_threshold()方法

import gc

print(gc.get_threshold()) #(700, 10, 10)

700即是垃圾回收启动的阈值

可以使用 set_threshold()方法重新设置

两个10是与分代回收相关的阈值

分代回收

Python同时用分代(generation)回收的策略。进程运行过程往往会产生大量的对象,许多对象很快产生和消失,但也有一些对象长期被使用。存活时间越久的对象,存在的意义价值可能越高。

(注意引用环的影响)

python 对象的分代

Python将所有的对象分为0,1,2三代。新建对象都是0代对象。当某一代对象经历过垃圾回收,依然存活,那么它就被归入下一代对象。

垃圾回收启动时,一定会扫描所有的0代对象。如果0代经过一定次数垃圾回收,那么就启动对0代和1代的扫描清理。当1代也经历了一定次数的垃圾回收后,那么会启动对0,1,2,即对所有对象进行扫描。

这两个次数即上面get_threshold()返回的(700, 10, 10)返回的两个10。也就是说,每10次0代垃圾回收,会配合1次1代的垃圾回收;而每10次1代的垃圾回收,才会有1次的2代垃圾回收。

同样可以用set_threshold()来调整,比如对2代对象进行更频繁的扫描。

import gc

gc.set_threshold(700, 10, 5)

为了回收这样的引用环,Python复制每个对象的引用计数,可以记为gc_ref。假设,每个对象i,该计数为gc_ref_i。Python会遍历所有的对象i。对于每个对象i引用的对象j,将相应的gc_ref_j减1。

在结束遍历后,gc_ref不为0的对象,和这些对象引用的对象,以及继续更下游引用的对象,需要被保留。而其它的对象则被垃圾回收。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值