深浅拷贝大法
为什么这么困啊,怎么每天都这么困啊,我感觉我快羽化而登仙了啊干!
但是就算我这么困,我也还是要给你们打气,今天的憨憨们有没有给自己打气啊!相信自己,哦吼吼吼吼吼
今日洗脑金句:今天不学习,明天变傻逼。
python深浅拷贝
一、引言
在python中, 对象赋值实际上就是对象的引用。当创建一个对象,然后把它赋值给另一个变量的,python并没有拷贝这个对象,而只是拷贝了这个对象的引用。
针对一个列表,一般有三种方法,分别为为拷贝、浅拷贝、深拷贝
注意:拷贝/浅拷贝/深拷贝都是针对可变类型数据而言的
1.1、可变or不可变
这个没什么好讲的,之前都讲过了,深浅拷贝只针对可变数据类型而言,也就是列表啊字典啊元组啊集合啊之类的,我不知道还有没有其他的,我只知道这么多,别问,问就是只知道这么多
二、拷贝
我们之前说过了什么?
对,什么也没说过。
其实,拷贝就是赋值啦。意思是什么呢,就是a如果是b的拷贝对象,那么如果b的内部有什么变化,a都会变,b拉坨屎,a的体重也会减轻。因为他俩是同一根绳子上的蚂蚱啊,引用的对象都是同一个啊,所以随便哪个变量对这个内存地址的内容改变,都会使全部指向这块内存地址的变量的变量值同时改变。
l1 = ['a', 'b', 'c', ['d', 'e', 'f']]
l2 = l1
l1.append('g')
print(l1)
['a', 'b', 'c', ['d', 'e', 'f'], 'g']
print(l2)
['a', 'b', 'c', ['d', 'e', 'f'], 'g']
三、浅拷贝
浅拷贝是一个比较叼的东西,方便大家理解,我只好祭出我璀璨星辰般的画技了。
import copy
a=[100,200,300,[666,SB,'-.-']]
b=copy.copy(a)
a.append('NB')
print(a)
print(b)
a的结果是什么很明显,a=[100,200,300,[666,'SB','-.-'],'NB']
那这个时候b呢? b=[100,200,300,[666,'SB','-.-']],能理解吗,因为copy.copy方法相当于是在内存里面重新开辟了一个空间来放了一个和a一毛一样的列表,所以a的改变不会引起b的改变。
那么! 如果
a[3].append('hahaha')
print(a)
print(b)
这个的结果会是什么呢?
a=[100,200,300,[666,'SB','-.-','hahaha'],'NB']
b=[100,200,300,[666,'SB','-.-','hahaha'],'NB']
这个时候的你,一定满头疑惑,为什么啊,不是说说两个内存不同的吗,都是单独的啊,哦,敢情我给你们画的图都白瞎了?给老子看上面的图,看到没,虽然他们是两个内存空间,但是他们的元素如果也是可变类型的话,那是不会开辟新空间的,就会指向同一个了,然后这时候这个内置列表的值改变了,由于他们都指向它,所以都会改变,这就是浅拷贝。懂了吧。
别急,你们一定不懂的。慢慢想想。
四、深拷贝
既然从拷贝到浅拷贝你们都看过了,那你们一定发现了规律了吧,深拷贝一定比浅拷贝还要叼一点的东西。
没错,深拷贝的东西,随你原来的怎么搞,他都不变化。
import copy
l1 = ['a', 'b', 'c', ['d', 'e', 'f']]
l2 = copy.deepcopy(l1)
l1.append('g')
print(l1)
['a', 'b', 'c', ['d', 'e', 'f'], 'g']
print(l2)
['a', 'b', 'c', ['d', 'e', 'f']]
l1[3].append('g')
print(l1)
['a', 'b', 'c', ['d', 'e', 'f', 'g'], 'g']
print(l2)
['a', 'b', 'c', ['d', 'e', 'f']]
综上所述:就一句话概括了这仨。
拷贝: 当b为a的拷贝对象时,a内的可变类型变化,b变化;a内的不可变类型变化,b变化, 简单的赋值。
浅拷贝:当b为a的浅拷贝对象时,lt内的可变类型变化,b变化;a内的不可变类型变化,b不变化,copy.copy() ,可变数据的类型中的内置方法.copy()
深拷贝: 当b为a的深拷贝对象时,a内的可变类型变化,b不变化;a内的不可变类型变化,b不变, copy.deepcopy()
草。。怎么是三句话
异常处理
一、什么是异常
擦,这也要问。
异常就是程序运行时发生错误的信号(在程序出现错误时,则会产生一个异常,若程序没有处理它,则会抛出该异常,程序的运行也随之终止),在python中,错误触发的异常如下
1.1语法错误
语法错误,根本过不了python解释器的语法检测,必须在程序执行前就改正。
# 语法错误示范一
if
# 语法错误示范二
def test:
pass
# 语法错误示范三
class Foo
pass
# 语法错误示范四
print(haha
1.2 逻辑错误
# TypeError:int类型不可迭代
for i in 3:
pass
# ValueError
num=input(">>: ") #输入hello
int(num)
# NameError
aaa
# IndexError
l=['egon','aa']
l[3]
# KeyError
dic={'name':'egon'}
dic['age']
# AttributeError
class Foo:pass
Foo.x
# ZeroDivisionError:无法完成计算
res1=1/0
res2=1+'str'
二、异常种类
在python中不同的异常可以用不同的类型(python中统一了类与类型,类型即类)去标识,一个异常标识一种错误。
异常的种类有很多,可以讲,但是没有必要,因为你只需要一个万能报错就可以了
Exception
#基本语法为
try:
被检测的代码块
except 异常类型:
try中一旦检测到异常,就执行这个位置的逻辑
只用在异常类型那里写Exception就可以了,什么错误都能抓取。
试问你在考虑是用斧头杀猪还是用砍山刀杀猪的时候,有一门炮你还想那么多干什么?
try....except总结
把错误处理和真正的工作分开来
代码更易组织,更清晰,复杂的工作任务更容易实现;
毫无疑问,更安全了,不至于由于一些小的疏忽而使程序意外崩溃了;
抛出异常和断言就随便一笔带过吧,因为真的没有用, 抛出异常是什么,主动报错,这不是有病吗?
程序好好的,加了一句抛出异常,至少这不是我现有阶段会去接触的东西,断言呢,最早的时候没有pycharm,那这个做调试,一辈子都用不上了。
对于异常处理这个功能,我觉得比较多余,为什么呢,因为你一定会在可能出错的地方写try except,既然你都知道什么地方会错,那你直接去找错误就完事儿了,搞些花里胡哨的东西干什么。
基本的文件操作
一、文件是什么?
这个不讲了,前面讲过了
二、为什么要有文件?
内存无法永久保存数据,但凡我们想要永久保存数据都需要把文件保存到硬盘中,而操作文件就可以实现对硬件的操作。
三、如何用文件?
现在我们有一个需求需要把用户输入的账号密码存储到硬盘中,我们使用Python该如何操作呢?
name = 'nick'
pwd = '123'
3.1从硬盘读取数据
如果我们需要打开一个文件,需要向操作系统发起请求,要求操作系统打开文件,占用操作系统资源。Python中使用open()方法可以打开某个具体的文件,open()方法内写入文件路径。
open(r'/Users/mac/desktop/jupyter/pythonCourseware/32.txt')
如果给列表增加值,我们需要给列表赋值后才能给对应的列表增加值。文件也是如此。
lis = [1,2,3]
lis.append(4)
lis.append(5)
# 打开文件
f = open(r'/Users/mac/desktop/jupyter/pythonCourseware/32.txt')
print(f)
<_io.TextIOWrapper name='/Users/mac/desktop/jupyter/pythonCourseware/32.txt' mode='r' encoding='UTF-8'>
打开文件之后,文件不仅占用了内存,他还对应了操作系统打开的以文件,相当于使用文本编辑器打开了一个文件。并且我们说了我们操控文件只是为了读和写,因此打开文件并不是目的,读和写才是目的,接下来我们尝试如何读写文件。
# read模式打开文件
f = open(r'/Users/mac/desktop/jupyter/pythonCourseware/32.txt', mode='r')
# 读取文件内容,向操作系统发起读请求,会被操作系统转成具体的硬盘操作,将内容由硬盘读入内存
data = f.read()
print(data)
# 由于Python的垃圾回收机制只回收引用计数为0的变量,但是打开文件还占用操作系统的资源,所以我们需要回收操作系统的资源资源
# del f 只是回收变量f
f.close()
name = 'nick'
pwd = '123'
3.2写入数据
# write模式打开文件
f = open(r'/Users/mac/desktop/jupyter/pythonCourseware/32.txt', mode='w')
f.write("""name = 'nick'
pwd = '123'""")
f.close()
f = open(r'/Users/mac/desktop/jupyter/pythonCourseware/32.txt', mode='r')
data = f.read()
print(data)
name = 'nick'
pwd = '123'
CV好爽啊。
好他妈闪啊,我的眼睛看不见了
简单汇总一下
打开文件总而言之分为三步:
- 打开文件
- 读写
- 关闭
绝对路径和相对路径
一、绝对路径
- Windows系统绝对路径从盘符(C:\、D:\)开始写一个完整的路径。
- macos系统从根目录(/Users)开始写一个完整的路径。
二、相对路径
相对于当前执行文件所在的文件夹开始找。
f = open('32.txt') # 32.txt与该.md文档同路径位置
莫得了,别看了,今天内容就到这里了,撒花,鼓掌