• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

py学习

武飞扬头像
幽幽超友善
帮助3

变量赋值和引用

【变量赋值的本质】

  • 每当定义一个新变量时,就会在内存中开辟一块空间用于数据存储。
  • 所以不同的变量,他们的内存地址是不同的。使用id()获取内存地址,使用is判断变量内存地址是否相同。
name = "zhangsan"
age = 18

# 如上述两个变量的赋值,就是定义了两个变量,变量名分别是name和age, 
# 本质上分别开辟了两块不同的内存控制,存放字符串"zhangsan"和数字18,
# 当我们访问name或age时,就会在对应的内存空间上获取值。

【变量引用的本质】

  • 把一个变量的内存地址,同时关联到另一个新变量上,于是两个变量对应一块内存地址。
a = 100
b = a 

# 此时a和b指向同一块内存空间,即id(a) == id(b)

通过以下两个示例,可以看出不可变类型变量和可变类型变量在引用时的区别

  • 示例1:将a指向另一块新的内存空间,b依然指向自己的内存空间
a = 100
b = a

a = 200
print(a, b)   # 200 100
  • 示例2:a和b指向同一块内存空间,只要这块内存空间上的元素发生变化时,关联的变量都受影响。
a = [1,2,3,4]
b = a
a[0] = 100
print(a[0], b[0])   # 100, 100

# 像字典、集合都属于可变类型的变量,引用时都存在上述现象

小整数池

python在内存上有一定的优化,比如小整数池和字符串驻留。

  • 【小整数池】:python解释器会在程序开始运行的时候就预先开辟一块内存空间,存放一部分整数。以后程序需要用到一些变量绑定到这些值时,直接绑定到这个内存地址上,不需要再逐个开辟空间(开辟空间访问硬件需要资源消耗),这是python的一种资源优化机制。范围:-5~256
  • 【字符串驻留】:Python的驻留机制对相同的字符串只保留一份拷贝,后续创建相同字符串时,不会开辟新空间,而是把该字符串的地址赋给新创建的变量。范围:英文字母、数字、下划线
a = 100
b = 100
print(a is b)   # True

a = 500
b = 500
print(a is b)   # False

a, b = 500, 500
print(a is b)   # True    在同一行定义两个相同值的变量,此时解释器做了优化,执行一个内存地址



a = "abc"
b = "abc"
print(a is b)   # True


a = "abc!"
b = "abc!"
print(a is b)   # False

垃圾回收机制

变量使用前需要先定义。

定义变量就是在内存中开辟一块空间用于数据储存,如果需要使用很多数据就需要开辟很多内存空间。

内存空间是有限的,如果定义了很多不在使用的变量,会导致内存浪费,甚至内存溢出的问题。

这就需要我们在变量使用后及时释放这个变量所占用的内存空间。

但是这个释放内存空间的工作是复杂且有分险的,幸运的是python解释器帮我们做了这部分工作。

python解释器内存主要使用引用计数的方式做垃圾回收。

什么是垃圾:垃圾指的是没有绑定变量名的值,也就是无法在访问的值,即没有用的值。

如何回收垃圾:通过引用计数的方式,每当这个值被引用,即被绑定到一个新的变量名上,引用计数加1

x = 10  # x绑定给值10,10的引用计数=1
y = x # y绑定给值10,10的引用计数=2
z = 10  # z绑定给值10,10的引用计数=3

# 通过赋值可以将变量名绑定到值,将引用计数增加
# 通过del 方法可以将变量名和值解绑,将引用计数减少

del z # z与它所绑定的值解绑,即值10的引用计数减为2
# 注意 del不是不是删除z的意思本质是接触变量名的绑定,内存回收的目的

import sys
sys.getrefcount(a)    # 查看引用计数

def f():
    import sys
    a = 10
    print(sys.getrefcount(a))
    b = a
    print(sys.getrefcount(a))
    c = [a]
    print(sys.getrefcount(a))
    del b
    print(sys.getrefcount(a))
    del c
    print(sys.getrefcount(a))

python垃圾回收机制,除了引用计数之外,还有【标记回收】、【分代回收】。

# 标记清除解决循环引用造成的问题
l1=[]
l2=[]
l1.append(l2)
l2.append(l1) 

del l1, l2

# 分代回收解决引用计数效率低的问题

迭代器

【可迭代对象(iterable)】指的是可以依次返回其内部成员的对象。比如字符串、列表、字典、文件等都是可迭代对象。

【迭代器(iterator)】内置函数iter(可迭代对象)得到迭代器,本质上迭代器也是可迭代对象。

# 可迭代对象, 从语法方面说就是那些具有__iter__的方法的对象
# 迭代器,从语法上说就是那些同时具有__next__和__iter__方法的对象。
  - 迭代器调用__next__方法会调用迭代器中的下一个值;
  - 迭代器调用__iter__方法返回迭代器本身;

示例:

>>> s={1,2,3}  # 可迭代对象s
>>> i=iter(s)  # i是迭代器
>>> next(i)    # 返回迭代器中下一个值
1
>>> next(i)
2
>>> next(i)
3
>>> next(i)  #抛出StopIteration的异常,代表无值可取,迭代结束

迭代器优缺点:

  • 优点:惰性取值;每次只取一个数据,不占内存。
  • 缺点:只能往后依次取值,不能返回头往前取值。就像象棋中的卒,只进不退。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhhchbcc
系列文章
更多 icon
同类精品
更多 icon
继续加载