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

  • 相关阅读:
    【转】【SEE】基于SSE指令集的程序设计简介
    【转】【Asp.Net】asp.net服务器控件创建
    ControlTemplate in WPF ——ScrollBar
    ControlTemplate in WPF —— Menu
    ControlTemplate in WPF —— Expander
    ControlTemplate in WPF —— TreeView
    ControlTemplate in WPF —— ListBox
    ControlTemplate in WPF —— ComboBox
    ControlTemplate in WPF —— TextBox
    ControlTemplate in WPF —— RadioButton
  • 原文地址:https://www.cnblogs.com/chanyuli/p/11311278.html
Copyright © 2011-2022 走看看