字符编码和文件操作

编码的历史

  事实上计算机只认识 0 和 1,然而我们却可以通过计算机来显示文本,这就是靠编码实现的。编码其实就是约定的一个协议,比如 ASCII 编码约定了大写字母 A 对应十进制数 65,那么在读取一个字符串的时候,看到 65,计算机就知道这是大写字母 A 的意
思。由于计算机是美国人发明的,所以这个 ASCII 编码设计时只采用 1 个字节存储(事实上只用了 7 位,1 个字节有 8 位),包含了大小写英文字母、数字和一些符号。但是计算机在全世界普及之后,ASCII 编码就成了一个瓶颈,因为 1 个字节是完全不足
以容纳各国语言的。大家都知道英文只用 26 个字母就可以组成不同的单词,而汉字光常用字就有好几千个,至少需要 2 个字节才足以存放,所以后来中国制订了 GB2312 编码,用于对汉字进行编码。然后日本为自己的文字制订了 Shift_JIS 编码,韩国为自己
的文字制订了 Euc-kr 编码,一时之间,各国都制订了自己的标准。不难想象,不同的标准放在一起,就难免出现冲突。这也正是为什么最初的计算机总是容易看到乱码的现象。
为了解决这个问题,Unicode 编码应运而生。Unicode 组织的想法最初也很简单:创建一个足够大的编码,将所有国家的编码都加进来,进行统一标准。

字符编码

  编码
    说简单的就是将人类能够读懂的字符编码成计算机能够直接读懂的字符

  解码
    解码就是计算机将人类不能够读懂的字符解码成人类能够看得懂得字符。

  str1 = '春游去动物园'
  # 编码 encode
  print(str1.encode('gbk'))  # b'\xb4\xba\xd3\xce\xc8\xa5\xb6\xaf\xce\xef\xd4\xb0'
    """
    字符串前面如果加了字母b 表示该数据类型为 bytes类型
    bytes类型可以看成是二进制
    """
  #解码 decode
  str2 =   b'\xb4\xba\xd3\xce\xc8\xa5\xb6\xaf\xce\xef\xd4\xb0'
  print(str2.decode('gbk'))  # 春游去动物园
  """
    当我们在后期进行网络开发的时候,数据都必须是二进制格式。
  """

  在python解释器层面
  由于python2解释器出现的时间非常的早,所以导致python2解释器默认的编码是ASCII码,这是美国发明的,里面只记录了英文并没有中文,当我们的程序中有中文时,一运行程序就会报错。目前有两种解决这类的问题。
  1.文件头:必须写在文件的最上方 告诉解释器使用指定的编码
     # coding:utf8
     # -*- coding:utf8 -*-  美化写法
  2.字符前缀:在使用python2解释器的环境下定义字符串习惯在前面加u
     name = u'春游去动物园'
  
  在python3中我们就不会出现这种问题,因为python3解释器默认编码是utf8

文件操作

  1.文件操作简介
    说得简单就是通过python代码来实现对文件的一些操作,例如拷贝,移动,修改等等。
  2.代码操作文件的流程
    1.打开文件、创建文件
    2.编辑文件内容
    3.保存文件内容
    4.关闭文件

   3.基本结构
      结构1(了解即可):
        f1 = open()
        f1.close()
      结构2(推荐使用):
        with open() as f:
            pass
    一.打开文件
        打开文件我们使用open函数,先用Python内置的open()函数打开一个文件,创建一个file对象,相关的方法才可以调用它进行读写
        f1 = open('文件的地址(相对路径或者绝对路径)', '文件的操作模式(r,w,a)', encoding='编码格式')
        f1 = open('a.txt','r',encoding='utf8')

    二.文件的读写模式
        r	read	只读模式:只能读不能写
        w	write	只写模式:只能写不能读
        a   append   只追加模式:在文件末尾添加内容

        r模式
          路径不存在时会直接报错
          read()方法 
          一次性读取文件内所有的内容,但是我们需要注意的是当我们一次读取太大的文件时,我们的内存会爆,所以这个并不使用与读取大文件。
          使用read(),返回所有文本内容
          f.read
      
          readline()
          f.readline() 会从文件中读取单独的一行。换行符为 '\n'。f.readline() 如果返回一个空字符串, 说明已经已经读取到最后一行。
         with open('a.txt', 'r', encoding='utf8') as f:
            print(f.readline()) # 111|111|

          readlines()方法
          f.readlines() 将以列表的形式返回该文件中包含的所有行,列表中的一项表示文件的一行。
          with open('a.txt', 'r', encoding='utf8') as f:
              print(f.readlines()) # ['111|111|\n', '222|222|\n']
           
          for循环
          with open('a.txt', 'r', encoding='utf8') as f:
                for i in f:
                    print(i)
            # 1
            # 
            # 2
            # 
            # 3
            # 
            # 4
            # 
            # 5

         w模式
           路径不存在:自动创建文件
           路径存在:先清空文件内容 之后再写入数据
           write()方法
           write()方法可将任何字符串写入一个打开的文件。需要重点注意的是,Python字符串可以是二进制数据,而不是仅仅是文字。write()方法不会在字符串的结尾添加换行符('\n'):
           with open('a.txt','w',encoding='utf8') as f:
              f.write('1.春游去动物园\n')
              f.write('2.春游去动物园\n')
              f.write('3.春游去动物园\n')
           """
            换行  最早的时候:\r\n
            为了节省空间支持一个字符 根据操作系统的不同可能有所区别
                \n 、 \r
           """
           writelines()
           使用writelines,以列表的方式写
           with open('a.txt','w',encoding='utf8') as f:
              f.writlines(['11','22','33'])

        a模式
          打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
          with open('a.txt','a',encoding='utf8') as f:
            f.write('111111')

         a模式和w模式的异同点:
         相同点:在打开的文件不关闭的情况下,连续的写入,新写的内容总会跟在前写的内容之后
         不同点:以 a 模式重新打开文件,不会清空原文件内容,会将文件指针直接移动到文件末尾,新写的内容永远写在最后

    三.文件的操作模式
        t模式
          文本模式 是默认的模式
            r	rt
            w	wt
            a	at
         1.该模式只能操作文本文件
         2.该模式必须要指定encoding参数
         3.该模式读写都是以字符串为最小单位
        b模式    
	  二进制模式  可以操作任意类型的文件
    	     rb  不能省略b
             wb  不能省略b
             ab  不能省略b
          1.该模式可以操作任意类型的文件
          2.该模式不需要指定encoding参数
          3.该模式读写都是以bytes类型为最小单位

          b模式对比t模式:
          1、在操作纯文本文件方面 t 模式帮我们省去了编码与解码的环节,b模式则需要手动编码与解码,所以此时t模式更为方便。
          2、针对非文本文件(如图片、视频、音频等)只能使用b模式。
          
          rb
          with open('a.txt', 'rb') as f:
              print(f.read()) #_b'111|111|\n222|222|\n'

文件内置方法

支持for循环:一行行读取文件内容(推荐使用)  内存中同一时刻只会有一行内容

f1.close():关闭文件

f1.flush():清除输出缓冲区  (相当于主动按了ctrl+s(保存))    

f1.write():写入文件内容(字符串或者bytes类型)

f1.writelines(line):写入序列line中的所有字符串

f1.writable():判断文件是否可写

f1.read(n):最多读取n个字节

f1.readlines():结果是一个列表 里面的各个元素是文件的一行行内容

f1.readline([n]):读取单行输入的最多n个字符,如果省略n,则读取整行

f1.readable():判断当前文件是否可读

f1.encoding:文件编码。如果没有使用任何编码该值为none

f1.closed:布尔值,表示状态,已打开则False,已关闭则为True

f1.tell():返回当前文件指针            

作业

1.编写一个简易版本的拷贝程序
	路径全部自定义
        old_path = input('请输入旧文件地址: ').strip()
        new_path = input('请输入新地址: ').strip()
        with open(f'{old_path}', 'rb') as f:
            data = f.read()
        with open(f'{new_path}', 'wb') as f1:
            f1.write(data)
2.结合文件编写用户注册登录功能
	# 提前先创建一个空的userinfo.txt
	用户注册 数据保存到文件中
    用户登录 数据来源于文件
    1.必须给我写出来
    	单用户注册登录
    2.拔高练习
    	多用户注册登录
try:
    f = open('a.txt', 'rb')
    f.close()
except  FileNotFoundError:
    f = open('a.txt', 'wb')
    f.close()
finally:
    while True:
        print(
            """
            1.注册
            2.登入
            3.退出
            """)
        choice = input('请输入指令: ').strip()
        if choice == '1':
            username = input('请输入你的用户名: ').strip()
            password = input('请输入你的密码: ').strip()
            with open('a.txt', 'rb') as f1:
                for i in f1:
                    if username == i.decode('utf8').split('|')[0]:
                        print('账号已经存在')
                        break
                else:
                    with open('a.txt', 'ab') as f1:
                        add = username + '|' + password + '|\n'
                        f1.write(add.encode('utf8'))
        elif choice == '2':
            username = input('请输入你的用户名: ').strip()
            password = input('请输入你的密码: ').strip()
            with open('a.txt', 'rb') as f1:
                for i in f1:
                    if username == i.decode('utf8').split('|')[0] and password == i.decode('utf8').split('|')[1]:
                        print('登入成功')
                        break
                else:
                    print('账号或密码错误')
        elif choice == '3':
            break
        else:
            print('请输入正确的指令')
posted @ 2022-03-14 16:58  春游去动物园  阅读(96)  评论(0编辑  收藏  举报