存值个数 | 数据类型 |
---|---|
单个值 | 数字,字符串 |
多个值(容器) | 列表,元组,字典,集合 |
可变or不可变 | 数据类型 |
---|---|
可变 | 列表,字典,集合 |
不可变 | 数字,字符串,元组 |
有序or无序 | 数据类型 |
---|---|
有序(可按索引取值) | 字符串,列表,元组 |
无序 | 字典,集合 |
访问类型 | 数据类型 |
---|---|
直接访问 | 数字 |
顺序访问(序列类型) | 字符串,列表,元组 |
key值映射(映射类型) | 字典 |
在python中,对象赋值实际上是对象的引用。当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用。拷贝一般有三种方法:拷贝,浅拷贝,深拷贝。
拷贝/浅拷贝/深拷贝都是针对可变数据类型而言我们这里使用列表作为演示
##当我们定义了一个列表,并且要将这个列表赋值给另一个列表的时候
a = [1,2,3,4]
b = a
a.append(5)
print(a) # [1, 2, 3, 4, 5]
print(b) # [1, 2, 3, 4, 5] ##我们可以看到a列表改变了b列表也跟着改变,这是因为这个赋值动作只是让b列表获取a列表的引用,a与b引用的是同一个列表。
##浅拷贝是使用copy包的中copy方法或者列表的内置方法copy实现的
import copy
a = [1,2,3,4]
b = copy.copy(a)
a.append(5)
print(a) # [1, 2, 3, 4, 5]
print(b) # [1, 2, 3, 4] ##我们可以看到a列表的改变不能再影响到b列表了。这是因为b列表新开辟了一个内存空间并将a列表中的指向全部复制一遍到列表b中。
但是,还有一个问题,如果列表中还有一个引用列表呢?
import copy
a = [1,2,3,[4,5]]
b = copy.copy(a)
a.append(5)
print(a) # [1, 2, 3, [4, 5], 5]
print(b) # [1, 2, 3, [4, 5]] ##看上去好像没有什么变化,但是我们改变一下添加的位置
a[3].append(6)
print(a) # [1, 2, 3, [4, 5, 6], 5]
print(b) # [1, 2, 3, [4, 5, 6]] ##我们可以看到,当改变的是列表里面的列表的时候b列表也会随着a列表的改变而改变。这是因为,copy是将a列表的指向也全部都复制下来,那么列表中的那个列表的引用也拷贝下来了。虽然a列表和b列表看着没有什么关系,但是他们内部的列表引用的是同一个内存地址。所以当a列表改变了b列表也会随着改变。
##既然出现了这种情况,那么肯定是有一个解决办法的。那就是copy包中的深拷贝。
import copy
a = [1,2,3,[4,5]]
b = copy.deepcopy(a)
a.append(5)
print(a) # [1, 2, 3, [4, 5], 5]
print(b) # [1, 2, 3, [4, 5]] ##看上去好像也没有什么变化,那让我们改变一下添加的位置
a[3].append(6)
print(a) # [1, 2, 3, [4, 5, 6], 5]
print(b) # [1, 2, 3, [4, 5]] ##由这里可以看出来a列表是真的和把列表没有任何关系了。但是这种方法特别浪费内存的,因为不仅仅是外面的列表要开辟一个空间,列表里面的列表也是要开辟一个新空间。
异常就是程序运行时发生错误的信号(在程序出现错误时,则会产生一个异常,若程序没有处理它,则会抛出该异常,程序的运行也随之终止)
语法错误,根本过不了python解释器的语法检测,必须在程序执行前就改正。
##一般这种错误IDE工具会给你标出来
##例如:
1.if
2.name =
print(name) # NameError
dic = {'name':'Gredae'}
print(dic['age']) # KeyError
##如果我们知道这个会出现异常
age = input('请输入一个数').strip()
if age.isdigit(): # 只有在age为字符串形式的整数时,下列代码才不会出错,该条件是可预知的
age = int(age)+1
print(age)
##如果我们无法预测这个地方到底会不会出现异常可以这样写
try:
被检测的代码块
except 异常类型:
try中一旦检测到异常,就执行这个位置的逻辑
举例:
a = input('请输入一个数').strip()
if a.isdigit(): # 只有在a为字符串形式的整数时,下列代码才不会出错,该条件是可预知的
age = int(age)
try:
print(100/a)
except ZeroDivisionError:
print('除数不能为零')
##当我们输入的数是零的时候try里面的输出语句就会报错,让except所捕获到这个异常是不是和我定义的异常一样,如果一样我就执行except里面的内容
但是,如果发生了未指定异常的时候就无法处理了。
s = 'hello'
try:
a = int(s)
except IndexError as e: # 未捕获到异常,程序直接报错
print(e)
当发生这种情况的话只能将可能会碰到的异常都写上去
s = 'hello'
try:
a = int(s)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e
当然,还有一种方法就是使用万能的Excption
s = 'hello'
try:
a = int(s)
except Exception as e:
print(e)
如果我们需要无论是有没有出现错误都执行的话可以使用finally
s = 'hello'
try:
int(s)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e)
finally:
print('无论异常与否,都会执行该模块,通常是进行清理工作')
原文:https://www.cnblogs.com/Gredae/p/11311593.html