zoukankan      html  css  js  c++  java
  • python day07

    1、字符编码

    文件是操作系统中的一个虚拟概念。文件是以计算机硬盘为载体存储在计算机上的信息集合,文件可以是文本文档、图片、程序,等等。在系统运行时,计算机以进程为基本单位进行资源的调度和分配;而在用户进行的输入、输出中,则以文件为基本单位。大多数应用程序的输入都是通过文件来实现的。

      在初期编写程序时,接触最多的是文本文件,比如,在注册和登录功能中,用户名和密码要存储在文件里,python程序也是写成文本文件的形式。

    执行一个python文件的过程:

      • Cpython解释器加载到内存

      • py文件从硬盘加载到内存

      • Cpython解释器向CPU发出指令,处理py文件,逐行识别文本的语法

    打开一个文本文档的过程:

      • 1 •启动文本编辑器(程序加载到内存),开始编辑,编辑时我们看到即时输入的内容是存在了内存

      • 2 •在输入→显示的过程中,涉及到中文字符→二进制→中文字符的过程

      • 3 •写完保存,编辑器把内存中的数据保存到硬盘

    首先来讨论一下• 2 •,字符→二进制→字符的过程,就是编码(encode)(输入),解码(decode)(输出),的过程。

      最开始计算机出现,只在英文环境里使用,所以编码解码只考虑英文字符和二进制,具体用哪些二进制数字表示哪个符号,经最早的这批人达成一致,这就是ASCII码。

      后来计算机普及,每个国家都产生了自己的语言与二进制的对应标准,比如中国的GBK,因为各个国家不统一,导致了这样的问题:汉语国家编写的软件,在其他语系国家里不能使用,因为他们的计算机中没有汉语字符与二进制的对照关系!为了解决这样的问题,各国统一,unicode码诞生了,它将很多国家的字符与二进制的关系都包含在内,统一使用16位二进制数字表示各国字符。

      结果就是,我们在自己的电脑文本编辑器里输入一个日文字符,编码到内存,显示(输出)的时候,这16位二进制数字会解码成日文,显示出来,而不会出现乱码的问题。

      可是再后来,使用计算机的过程中,又发现了新问题:在英语系国家的编程者发现,原来采用ASCII码,用8位二进制表示字符,而现在需要16位,输入的数据存入硬盘的时间几乎长了一倍!为了解决这样的问题,又出现了UTF-8(8-bit Unicode Transformation Format),这是一种针对Unicode的可变长度字符编码,它会识别unicode编码的二进制表示的字符是什么语言的字符,并分配不同的字节,比如,如果是英文,就用1个字节存储到硬盘,如果是中文,就用3个字节存到硬盘...这是• 3 •的过程

      有了UTF-8之后,只要我们写一个文件,保存成utf-8编码格式,在任何国家的电脑上也能通用,而且占的空间更小,存取更快!是不是觉得,utf-8可以完全取代unicode了!理论上的确是这样,但这里又存在一个历史遗留问题了,在这之前,很多国家都用自己国家的编码标准编写了软件,而utf-8里只有与unicode 一 一对应的关系,并没有直接和GBK,shift-jis等标准建立联系,所以直至现在,我们的计算机内存采用的,仍然是unicode.就像python3刚推出,而很多python2的软件都不能用python3运行,导致很多公司和个人拒绝使用python3,于是龟叔迫不得已推出python2.7一样,我们需要unicode来作为阶段性的过渡。

      但是如果以后每个人写文件,都采用utf-8格式保存,等足够长的时间后,就可以废弃unicode标准了,也就不会存在因为编码解码而导致的程序报错和乱码问题!!

      这张图可以帮助你理解编码、解码的过程和乱码、报错的原因:

    总结来说,字符编码就是字符按照某种标准转换(编码)成数字(二进制位)的过程,这个标准叫字符编码表。而解决乱码问题的关键,就是以什么格式编码的,就用什么格式解码,要保证编码解码一致,最好清晰的,人为的指定编码解码方式。比如在文件最上方添加文件头:  #coding:utf-8(文件当初存的字符编码)。

    python解释器默认的字符编码:python3:默认utf-8;python2:默认ASCII。 

    字符的指定编码转换方法:

    x='张'
    res=x.encode('gbk')
    m=res.decode('gbk')

    2、文件处理

    文件是操作系统为了方便用户和应用程序管理磁盘空间,提供的虚拟单位,文件对应着磁盘空间,为了永久在磁盘存储数据,就要使用文件。应用程序和用户对文件进行读写操作都是向操作系统发送请求,由操作系统对外发送指令。

    对文件进行操作首先要找到文件,也就是知道文件路径,路径有两种:绝对路径和相对路径。

      • 绝对路径   是文件所在文件夹在系统中的完整位置    windows系统:D:A_my_practice

              linux系统:/use/local/lib

      • 相对路径   是相对于执行文件所在文件夹的位置。

    找到文件后,就可以对文件进行打开、读写、关闭操作。

    复制代码
    #    打开文件   路径            指定读写模式(只读,以text的格式)   指定当时保存的编码格式(也就是指定解码格式)
    file1 = open(r'D:A_my_practicea.txt', mode='rt', encoding='utf-8')
    # 读文件
    res = file1.read()
    print(res)
    # 关闭文件
    file1.close()
    复制代码

    这样打开文件,操作结束后一定要关闭,这里涉及执行文件时的内存管理:

    当打开一个文件时,file1首先是python程序内存里的一个变量,占用python的内存空间,而file1的值指向一个文件,文件是操作系统这个程序产生的,所以也占用操作系统的内存,python解释器有自己的垃圾回收机制,而操作系统没有,为了不浪费内存,需要我们主动关闭文件。

    还有一种打开方法,不用主动关闭:

    with open('a.txt',mode='wt',encoding='utf-8') as f:
        f.write("123
    ")

    再with...的子代码块结束之后,文件就会关闭。

    以上面的代码为例,总结文件的基本操作:

    打开文件有两种方式如上,open()括号内都要指定路径,r‘路径’ 表示,路径字符串是原生字符串,里面的 没有转义的含义。mode指定文件的操作模式:

    r 只读,从文件头读到文件末尾,文件不存在时报错 b 以bytes为单位打开(二进制)
    w

    只写,在打开时将文件内容清空,写入指定内容

    文件不存时创建空文件

    t 以字符为单位打开
    a

    追加写,打开时指针移到行末,追加写入的内容

    文件不存时创建空文件

    +

    r+  可读可写

    w+ 可写可读

    a+  可追加写可读

    
    
    with open('a.txt', 'rb', ) as file1:  # b 模式下不能指定字符编码
    res = file1.read() # 一次性读全部内容
    res1 = file1.readline() # 逐行读
    res2 = file1.readlines() # 逐行读,将内容存放到列表
    res3 = file1.readable() # 判断是否可读
    with open('a.txt', 'wt', encoding='utf-8') as file1:
        res = file1.write()  # 清空后写入
        res1 = file1.writelines()  # 传入一个元素是字符串的列表,将元素逐个写入
        res3 = file1.writable()  # 判断是否可写

    实现copy 功能:

    with open('a.txt','rb') as file1,open('b.txt','wb') as file2:
        file2.write(file1.read())

    这种方法一次性读取文件全部内容,在内存中完成复制后存入磁盘。

    缺点:如果文件过大,会占用过多内存

    with open('a.txt','rb') as file1,open('b.txt','wb') as file2:
        for line in file1:
            file2.write(line)

    这种方法逐行读取file1的内容,逐行写入file2.

    优点:执行时只有一行在内存中,占用内容少。

    实现修改文件功能,原理类似copy功能:

    with open('a.txt','rt',encoding='utf-8') as f1:
        msg = f1.read()
        new_msg = msg.replace("world","python")
    with open('a.txt','wt',encoding='utf-8') as f2:
        f2.write(new_msg)

    优点:节省磁盘空间,执行过程,只有一份数据在磁盘。编辑器采用此种方式。

    缺点:如果文件过大,会占用过多内存

    复制代码
    import os
    
    with open('a.txt', 'rt', encoding='utf-8') as f1, 
            open('.b.txt.swap', 'wt', encoding='utf-8') as f2:
        for line in f1:
            f2.write(line.replace("world", "python"))
    
    os.remove('a.txt')
    os.rename('.b.txt.swap', 'a.txt')
    复制代码

    缺点:占用磁盘空间

    优点:节省内存

  • 相关阅读:
    flink-sql-client使用kafka表格
    flink 使用sql实现kafka生产者和消费者
    利用scan迁移部分单点redis数据到RedisCluster
    flink按事件时间排序
    Linux下面 多线程死锁问题的调试
    大数据开发工具漫谈
    如何撰写一个分布式计算平台的作业调度器?
    (随用随总结)Linux下面的特殊权限&不同的文件类型
    【javascript小案例】从0开始实现一个俄罗斯方块
    mysqldumpslow简单使用方法-mysqldumpslow详细用法
  • 原文地址:https://www.cnblogs.com/zhouyuquan/p/10022285.html
Copyright © 2011-2022 走看看