zoukankan      html  css  js  c++  java
  • 深浅拷贝大法

    为什么这么困啊,怎么每天都这么困啊,我感觉我快羽化而登仙了啊干!

    但是就算我这么困,我也还是要给你们打气,今天的憨憨们有没有给自己打气啊!相信自己,哦吼吼吼吼吼

    今日洗脑金句:今天不学习,明天变傻逼。

    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']

    三、浅拷贝

    浅拷贝是一个比较叼的东西,方便大家理解,我只好祭出我璀璨星辰般的画技了。

    img

    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']

    这个时候的你,一定满头疑惑,为什么啊,不是说说两个内存不同的吗,都是单独的啊,哦,敢情我给你们画的图都白瞎了?给老子看上面的图,看到没,虽然他们是两个内存空间,但是他们的元素如果也是可变类型的话,那是不会开辟新空间的,就会指向同一个了,然后这时候这个内置列表的值改变了,由于他们都指向它,所以都会改变,这就是浅拷贝。懂了吧。

    别急,你们一定不懂的。慢慢想想。

    img

    四、深拷贝

    既然从拷贝到浅拷贝你们都看过了,那你们一定发现了规律了吧,深拷贝一定比浅拷贝还要叼一点的东西。

    没错,深拷贝的东西,随你原来的怎么搞,他都不变化。

    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中,错误触发的异常如下

    116-异常处理-异常图.jpg?x-oss-process=style/watermark

    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就可以了,什么错误都能抓取。

    试问你在考虑是用斧头杀猪还是用砍山刀杀猪的时候,有一门炮你还想那么多干什么?

    img

    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好爽啊。

    img

    好他妈闪啊,我的眼睛看不见了

    img

    简单汇总一下

    打开文件总而言之分为三步:

    1. 打开文件
    2. 读写
    3. 关闭

    绝对路径和相对路径

    一、绝对路径

    • Windows系统绝对路径从盘符(C:、D:)开始写一个完整的路径。
    • macos系统从根目录(/Users)开始写一个完整的路径。

    二、相对路径

    相对于当前执行文件所在的文件夹开始找。

    f = open('32.txt')  # 32.txt与该.md文档同路径位置
    

    莫得了,别看了,今天内容就到这里了,撒花,鼓掌

    img

  • 相关阅读:
    hystrix基本介绍和使用(1)
    Java SPI机制用法demo
    python数据结构与算法——图的最短路径(Bellman-Ford算法)解决负权边
    python数据结构与算法——图的最短路径(Dijkstra算法)
    python数据结构与算法——图的最短路径(Floyd-Warshall算法)
    python数据结构与算法——图的广度优先和深度优先的算法
    python数据结构与算法——小猫钓鱼(使用队列)
    python数据结构与算法——栈
    python数据结构与算法——队列
    python数据结构与算法——链表
  • 原文地址:https://www.cnblogs.com/chanyuli/p/11311278.html
Copyright © 2011-2022 走看看