Python教程

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

本文主要是介绍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]}

 

 

 

这篇关于Python基础——变量可变不可变&深浅拷贝的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!