• python 文件操作和深浅copy


    一、编码的进阶

    1 str 与 bytes 形式

    s1 = 'alex'
    print(s1,type(s1))    #alex <class 'str'>
    s2 = b'alex'          
    print(s2.upper())     #b'ALEX'
    print(s2,type(s2))    # b'alex' <class 'bytes'>

    2,encode   解码     decode   解码 

    s1 = '中国'
    print(s1, type(s1))       #中国 <class 'str'>
    b1 = s1.encode('utf-8')
    print(b1,type(b1))        #b'xe4xb8xadxe5x9bxbd' <class 'bytes'>

        str ----> utf-8 bytes

    s1 = 'a太白'
    b1 = s1.encode('utf-8')
    print(b1)  # b'axe5xa4xaaxe7x99xbd'

        str ----> gbk bytes

    s1 = 'a太白'
    b1 = s1.encode('gbk')
    print(b1)  # b'axccxabxb0xd7'

      utf-8 bytes ----> str Unicode

    b3 = b'axe5xa4xaaxe7x99xbd'
    s2 = b3.decode('utf-8')
    print(s2)          #a太白

       utf-8 bytes       -------->     gbk bytes

    b3 = b'axe5xa4xaaxe7x99xbd'
    
    # 先将b3 转化成UNicode
    s = b3.decode('utf-8')
    
    # 再将 s 编码成 gbk
    b4 = s.encode('gbk')
    print(b4)  # b'axccxabxb0xd7'
    s1 = 'lao男孩'
    b1 = s1.encode('utf-8')
    s2 = b1.decode('utf-8')
    b2 = s2.encode('gbk')
    print(b2)

    二、文件操作初识

    计算机系统分为:计算机硬件,操作系统,应用程序三部分。

    我们用python或其他语言编写的应用程序若想要把数据永久保存下来,必须要保存于硬盘中,这就涉及到应用程序要操作硬件,众所周知,应用程序是无法直接操作硬件的,

    这就用到了操作系统。操作系统把复杂的硬件操作封装成简单的接口给用户/应用程序使用,其中文件就是操作系统提供给应用程序来操作硬盘虚拟概念,用户或应用程序通过操作文件,

    可以将自己的数据永久保存下来。

    .1.文件编码

    windows: 编码:gbk.

    linux,ms: 编码是utf-8

    2.操作文件的流程:

        1,打开文件,产生一个文件句柄.

        2, 对文件句柄进行相应的操作.

        3,关闭文件句柄.

    #1. 打开文件,得到文件句柄并赋值给一个变量
    f=open('a.txt','r',encoding='utf-8') #默认打开模式就为r
    
    #2. 通过句柄对文件进行操作
    data=f.read()
    
    #3. 关闭文件
    f.close()
    for打开文件
    with open('a.txt','w') as f:
        pass
     
    with open('a.txt','r') as read_f,
        open('b.txt','w') as write_f:
        data=read_f.read()
        write_f.write(data)
    with打开,不用close 

    3.打开文件的方式:

      r,w,a

      r+,w+,a+

      rb,wb,ab

      r+b,w+b,a+b

       默认使用的是r(只读模式)

    (1)文件的读     r       r+      rb    r+b

    read()   #全部读取

    f1 = open('r模式',encoding='utf-8')
    content = f1.read()
    print(content,type(content))
    f1.close()

    注:  r模式:  n 字符

            rb模式: n 字节

    f1 = open('r模式',encoding='utf-8')
    print(f1.read(3))  #读三个字符
    f1.close()
    f1 = open('r模式',mode='rb')
    print(f1.read(3)) #读三个字节
    f1.close()

    readline()   #按行读取

    f1 = open('r模式',encoding='utf-8')
    print(f1.readline().strip())
    f1.close()

    readlines()   # 返回一个list 列表的每个元素是源文件的每一行.

    f1 = open('r模式',encoding='utf-8')
    print(f1.readlines())
    f1.close()

    循环读取

    f1 = open('r模式',encoding='utf-8')
    for line in f1:
        print(line)
    f1.close()

    rb 以字节的形式读取  # 带b的一般操作的都是非文字类的文件.

    f = open('赵丽颖.jpg',mode='rb')
    content = f.read()
    f.close()

    r+ 读写模式:先读后写

    f1 = open('r模式',encoding='utf-8',mode='r+')
    content = f1.read()
    print(content)
    f1.write('666')
    f1.close()

    (2)文件的写       w      w+     wb    w+b

    W    # 没有文件,创建文件,写入内容

           # 如果有文件,先清空内容,后写入

    f = open('w模式',encoding='utf-8',mode='w')
    f.write('随便写一点')
    f.close()
    f = open('w模式',encoding='utf-8',mode='w')
    f.write('1alex is a lower man
    ')
    f.write('1alex is a lower man
    ')
    f.write('1alex is a lower man
    ')
    f.write('1alex is a lower man
    ')
    f.close()
    写多次
    f = open('w模式',encoding='utf-8',mode='w')
    for i in range(4):
        f.write('Alex is a lower man
    ')
    f.close()

    wb

    f = open('赵丽颖.jpg',mode='rb')
    content = f.read()
    f.close()
    
    f1 = open('美女.jpg',mode='wb')
    f1.write(content)
    f1.close()

    (3)文件的追加       a      ab      a+    a+b

    a 没有文件,创建文件,写入内容

    f = open('a模式',encoding='utf-8',mode='a')
    f.write('很多让人很有成就感的事情')
    f.write('很多让人很有成就感的事情')
    f.write('很多让人很有成就感的事情')
    f.close()
    f = open('a模式',encoding='utf-8',mode='a')
    f.write('666')
    f.close()

    (4)文件的其他操作

    f1 = open('r模式',encoding='utf-8')
    print(f1.fileno())  #   文件描述符 用不到
    f1 = open('其他操作方法',encoding='utf-8',mode='w')
    f1.write('jfkdlsfjdsafkds')
    f1.flush()  # 强制保存
    f1.close()

    readable writeable````````  是否可读,是否可写

    f1 = open('其他操作方法',encoding='utf-8')
    # print(f1.readable())  # True
    # f1.write('fdsafs')
    print(f1.writable())  # False
    if f1.writable():
        f1.write('fhdsklafjds')
    f1.close()

    seek  # 按照字节调整光标位置            (网络编程: FTP的作业,断点续传的功能. seek tell

    tell  # 获取光标的位置

    f1 = open('其他操作方法',encoding='utf-8')
    # f1.seek(9)  # 按照字节调整光标位置
    print(f1.tell())  # 获取光标的位置
    print(f1.read())
    print(f1.tell())
    f1.close()

    truncate  # 对原文件进行截取   他必须在可写情况下使用.

    f = open('其他操作方法',encoding='utf-8',mode='r+')
    f.seek(3)  # 调整光标对truncate不管用
    f.truncate(9)  # truncate都是从文件的开始进行截取,以字节为单位.
    f.close()

    (5)文件的改

    1,以读的模式打开原文件.

    2,以写的模式创建一个新文件.

    import os
    with open('alex自述',encoding='utf-8') as f1,
        open('alex自述.bak',encoding='utf-8',mode='w') as f2:
    # 3,将原文件内容读取出来,按照你的要求改成新内容,写入新文件.
        old_content = f1.read()
        new_content = old_content.replace('alex','sb')
        f2.write(new_content)
    # 4,删除原文件.
    os.remove('alex自述')
    # 5,将新文件重命名成原文件.
    os.rename('alex自述.bak','alex自述')
    import os
    with open('alex自述',encoding='utf-8') as f1,
        open('alex自述.bak',encoding='utf-8',mode='w') as f2:
    # 3,将原文件内容读取出来,按照你的要求改成新内容,写入新文件.
        for old_line in f1:
            new_line = old_line.replace('alex','sb')
            f2.write(new_line)
    
    # 4,删除原文件.
    os.remove('alex自述')
    # 5,将新文件重命名成原文件.
    os.rename('alex自述.bak','alex自述')

    三、深浅copy

    1,先看赋值运算。

    l1 = [1,2,3,['barry','alex']]
    l2 = l1
    
    l1[0] = 111
    print(l1)  # [111, 2, 3, ['barry', 'alex']]
    print(l2)  # [111, 2, 3, ['barry', 'alex']]
    
    l1[3][0] = 'wusir'
    print(l1)  # [111, 2, 3, ['wusir', 'alex']]
    print(l2)  # [111, 2, 3, ['wusir', 'alex']]

     赋值运算,l1与l2指向的是同一个内存地址,所以他们是完全一样的。

    2,浅拷贝copy

    #同一代码块下:
    l1 = [1, '太白', True, (1,2,3), [22, 33]]
    l2 = l1.copy()
    print(id(l1), id(l2))  # 2713214468360 2713214524680
    print(id(l1[-2]), id(l2[-2]))  # 2547618888008 2547618888008
    print(id(l1[-1]),id(l2[-1]))  # 2547620322952 2547620322952
    
    # 不同代码块下:
    >>> l1 = [1, '太白', True, (1, 2, 3), [22, 33]]
    >>> l2 = l1.copy()
    >>> print(id(l1), id(l2))
    1477183162120 1477183162696
    >>> print(id(l1[-2]), id(l2[-2]))
    1477181814032 1477181814032
    >>> print(id(l1[-1]), id(l2[-1]))
    1477183162504 1477183162504

     浅copy,只是在内存中重新创建了开辟了一个空间存放一个新列表,但是新列表中的元素与原列表中的元素是公用的。

    3,深拷贝deepcopy

    # 同一代码块下
    import copy
    l1 = [1, 'alex', True, (1,2,3), [22, 33]]
    l2 = copy.deepcopy(l1)
    print(id(l1), id(l2))  # 2788324482440 2788324483016
    print(id(l1[0]),id(l2[0]))  # 1470562768 1470562768
    print(id(l1[-1]),id(l2[-1]))  # 2788324482632 2788324482696
    print(id(l1[-2]),id(l2[-2]))  # 2788323047752 2788323047752
    
    # 不同代码块下
    >>> import copy
    >>> l1 = [1, '太白', True, (1, 2, 3), [22, 33]]
    >>> l2 = copy.deepcopy(l1)
    >>> print(id(l1), id(l2))
    1477183162824 1477183162632
    >>> print(id(0), id(0))
    1470562736 1470562736
    >>> print(id(-2), id(-2))
    1470562672 1470562672
    >>> print(id(l1[-1]), id(l2[-1]))
    1477183162120 1477183162312

    深copy,列表是在内存中重新创建的,列表中可变的数据类型是重新创建的,列表中的不可变的数据类型是公用的。

  • 相关阅读:
    其他魔术方法
    类型约束和类的魔术常量
    PHP对象遍历、内置标准类与数据转对象
    类的自动加载与对象的克隆
    PHP重载与接口
    面向对象
    PHP基础
    地下城与勇士的项目整理
    mysql建表
    jQuery
  • 原文地址:https://www.cnblogs.com/Xiao_Xu/p/10511791.html
Copyright © 2020-2023  润新知