Python基础——变量可变不可变&深浅拷贝

1. 深入了解数据 及其类型

  场景:别人使用我们的代码,传递了数据a 和数据b
  问题:如何知道它们分别是什么,以及如何使用?
name='beifan'

print("唯一表示(内存地址)", id(name))   #变量的内存地址
print("数据类型", type(name))      #获取变量类型
print("数据成员", dir(name))     #数据成员 = 属性(不可调用) + 方法(可调用的)
print("是否可以调用", callable(name))  #变量是否可调用
print("方法的用法:",help(name.index()))    #字符串name对应的index方法的用法

2.可变对象和不可变对象

2.1 可变对象

   列表,字典,集合,对原内存进行修改,id不变
复制代码
l = []
print("修改前的id = ", id(l)) 
l.append(123)
print("修改后的id = ", id(l))
print(l)

修改前的id = 1944158072960
修改后的id = 1944158072960
[123]

复制代码

 

2.2 不可变对象

数值、字符串、元组-------原内存未变,在新内存放入新值

复制代码
i = 123
print("修改前的id = ", id(i))
i += 1
print("修改后的id = ", id(i)) # 新的内存保存新的值
print(i)

修改前的id = 1824816697392
修改后的id = 1824816697424
124

复制代码

 

2.3 特殊情况

虽然也会创建新的对象,但是原对象没有发生变化
对于可变对象来说,也不一定每一次的修改,都是在原内存空间进行的
复制代码
l = [1, 2, 3]
print("l的ID", id(l))
l = l[:2]
print("l的ID", id(l))
print(l)

l的ID 1964630143104
l的ID 1964630095936
[1, 2]

复制代码
 

3、赋值说明

(1) = 赋值号,用来传递变量,而不是创建变量
(2) "sunny" 写在代码中的时候,内存已经创建好
复制代码
name = "sunny"  # 创建新的内存
new_name = name # 不是创建新变量,而是把已有变量,传递过来
print(id(name))
print(id(new_name))

2630317342640
2630317342640

复制代码

4.深拷贝和浅拷贝(针对可变对象)

4.1 浅拷贝--只为对象开辟了内存,没有为成员开辟内存

浅拷贝做了2件事情:
1、为“目标对象”创建副本
2、将“副本对象”的成员,指向“目标对象”的成员
也就是说,只为对象开辟了内存,没有为对象的成员开辟内存
复制代码
import copy

d = {
    "name": "beifan",
    "age": 18,
    "size": [89, 89, 89]
}
dd = copy.copy(d)  # 浅拷贝
dd['size'].pop()   #dd元素size修改后,d对应的也会更新
print("复制的字典", id(d), id(dd))  # 创建新的内存
print("字典中的字符串", id(d['name']), id(dd['name']))  # 没有创建新的内存
print("字典中的整数", id(d['age']), id(dd['age']))  # 没有创建新的内存
print("字典中的列表", id(d['size']), id(dd['size']))  # 没有创建新的内存
print(d) 
print(dd)

复制的字典 1375910854400 1375910887488
字典中的字符串 1375910887536 1375910887536
字典中的整数 1375905579792 1375905579792
字典中的列表 1375911344768 1375911344768
{'name': 'beifan', 'age': 18, 'size': [89, 89]}
{'name': 'beifan', 'age': 18, 'size': [89, 89]}

复制代码

4.2深拷贝---不仅对象开辟了内存,也为成员开辟内存

深拷贝做了3件事情:
(1) 为“目标对象”创建副本 (开辟内存)
(2) 为“目标对象的成员(以及成员的成员)”创建副本 (开辟内存) (开辟内存) (开辟内存) (开
辟内存)
(3) 将“副本对象”的成员,指向新创建的 ”副本成员“
复制代码
import copy

d = {
    "name": "beifan",
    "age": 18,
    "size": [89, 89, 89]
}
dd = copy.deepcopy(d) # 深拷贝
dd['size'].pop()   #dd元素size修改后,数据隔离,d不会更新,
print("复制的字典", id(d), id(dd))  # 创建新的内存
print("字典中的字符串", id(d['name']), id(dd['name']))  # 没有创建新的内存
print("字典中的整数", id(d['age']), id(dd['age']))  # 没有创建新的内存
print("字典中的列表", id(d['size']), id(dd['size']))  # 创建了新内存
print(d)
print(dd)

复制的字典 1667011608320 1667011962368
字典中的字符串 1667011641456 1667011641456
字典中的整数 1667010331408 1667010331408
字典中的列表 1667012098688 1667011963648
{'name': 'beifan', 'age': 18, 'size': [89, 89, 89]}
{'name': 'beifan', 'age': 18, 'size': [89, 89]}

复制代码

 

 

 

posted @   奋斗的sunny  阅读(102)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示