• python字符编码、文件处理、函数


    一、字符编码


      1、什么是字符编码
        把字符转换成计算机可识别的机器码(0,1)的过程,称之为字符编码。


      2、字符编码的类型

        1)现代计算机起源于美国,最早诞生也是基于英文考虑的ASCII
          ASCII:一个Bytes(字节)代表一个字符(英文字符、键盘上的所有其它字符),1Bytes=8bit,8bit可以表示为2的8次方种变化,即可以表示256个字符。
          ASCII最初只用了后攻位,127个数字,已经完全能够代表键盘上所有的字符了(英文字符/键盘的所有其他字符),后期将拉丁文也编码进了ASCII表,占用了最高位。
        2)为了满足中文,中国人定制了GBK
          GBK:2Bytes代表一个字符
          为了满足需求,各国家分别定制了自己的编码。日文编码Shift_JIS,韩文编码Euc-kr。
        3)各国编码遵循自己的标准,当在多语言混合的文本中,就会出现冲突,显示乱码。于是产生了unicode万国码。
          unicode:至少用2Bytes代表一个字符,2**16-1=65535,可代表655535个字符,因而兼容万国语言。
          由于至少使用2字节代表一个字符,对于英文文本来说,多占用了一倍的存储空间,于是产生了utf-8。    
        4)utf-8:对文本进行判断,中文使用3Bytes,英文字符只有1Bytes。
          ps:unicode与uft-8比较:
          unicode:简单粗暴,所有字符都是2Bytes,优点是字符->数字的转换速度快,缺点是占用空间大。(内存使用unicode速度快)
          utf-8:精准,对不同的字符用不同的长度表示,优点是节省空间,缺点是:字符->数字的转换速度慢,因为每次都需要计算出字符需要多长的Bytes才能够准确表示。(硬盘使用utf-8节省空间)


      3、字符编码的使用
        以文本编辑器举例,不管时打开读取还是修改都是在内存中打开。
        读取文件时,是decode的过程:把硬盘中utf-8格式的文本-》decode(翻译)-》内存unicode格式
        保存文件时,是encode的过程:把内存中unicode格式的文本-》encode(翻译)-》硬盘中utf-8格式


      4、python3与2中编码的区别

        python3中所有的字符串都会被识别成unicode 字符编码。
        python2中所有的字符串就是编码后的结果bytes字节。

    二、文件处理


      1、打开文件的两种方式:
        1)open函数打开文件后需要close关闭

          f = open('a.txt','r',encodeing='utf-8')
          data = f.read()
          print(data)
          f.close()

        2)with open打开文件后不需要关闭,使用with命令换行会自动缩进,缩进里的代码都是对文件的操作,退出缩进会自动关闭文件。

         with open('a.txt','r',encoding='utf-8') as f:
         data = f.read()
         print(data)

      2、文件操作模式:
        open与with参数都一样。
        参数一:a.txt,文件名,相对路径或绝对路径均可。
        参数二:'r',操作模式,
          r 只读,默认,文件不存在则报错,存在则读取,。
          w 只写,不可读,文件不存在则创建,存在则写入(会先清空再写入),。
          x 只写,不可读,文件不存在则创建,存在则报错。
          a 追加,可读,不存在则创建 ,存在则只追加内容。
        "+"表示可以同时读写某个文件
          r+ 读写
          w+ 写读
          x+ 写读
          a+ 写读
        "b"表示以字节的方式操作
          rb 或 r+b
          wb 或 w+b
          xb 或 x+b
          ab 或 a+b
        注:以b方式打开时,读取到的内容是了节类型,写入时也需要提供字节类型。
        参数三:encodeing='utf-8',指定字符编码。

      3、文件读取操作
        1)读取文件,以读r的方式打开文件,有则清空,无则报错
          f1 = open('a.txt',encoding='utf-8')
          data = f1.read()
          print(data)
        2)读取文件,输出两次时,默认第二次输出为空。
          因为读取是光标逐行读取的,第一次读取后光标会走到文件最后。
          如果第二次想要打印出文件内容,需要使用seek将光标重新定位一文件开始位置。
          f1 = open('a.txt','r', encoding='utf-8')
          print(f1) #查看读取属性
          print(f1.read())
          f1.seek(0)
          print(f1.read())

        3)判断文件是否可读 (true false)
          f1 = open('a.txt','r', encoding='utf-8')
          data = f1.readable()
          print(data)
          f1.close()
        4)逐行读取文件(不能把文件赋值),默认会打印换行符,使用end=''替换print自带的换行符为空
          f1 = open('a.txt','r', encoding='utf-8')
          print(f1.readline())
          print(f1.readline(),end='')
          print(f1.readline())
          f1.close()
        5)以列表形式显示文件
          f1 = open('a.txt','r', encoding='utf-8')
          print(f1.readlines())
          f1.close()

      4、文件写入操作
        1)写文件,以写w的方式打开文件,有则清空,无则创建
          逻辑为先清空内容,再写入,不重建文件,且不会修改文件创建时间,只更新修改时间
          f1 = open('a.txt','w', encoding='utf-8')
        2)判断文件是否可写 (true false)
          f1 = open('a.txt','w', encoding='utf-8')
          print(f1.writable())
        3)写入文件内容
          f1 = open('a.txt','w', encoding='utf-8')
          f1.write('111 222 333')
          f1.write(' 444 555 666')
          f1.close
        4)以列表格式写入文件内容
          f1 = open('a.txt','w', encoding='utf-8')
          f1.writelines(['111','222','333'])
          f1.close
        5)追加文件内容
          f1 = open('a.txt','a', encoding='utf-8')
          f1.write('777 888 999')
          f1.close)
        6)模拟文件修改,判断修改文件,循环文件,判断,逐条写入文件2,遇到匹配进行修改并写入修改后的内容,最后使用os模块覆盖原文件
          import os #导入os模块
          read_f = open('a.txt','r', encoding='utf-8')
          write_f = open('a.txt.swap','w', encoding='utf-8')
          for line in read_f.readlines(): #循环显示文件列表
            if line.startswith('111'): #判断如果以‘111’开头
              line='999 ' #修改111为999
            write_f.write(line) #读取一条写入到.swap文件,如匹配判断条件,则写入修改后的内容
          read_f.close()
          write_f.close()
          #覆盖原文件
          os.remove('a.txt') #删除原文件
          os.rename('a.txt.swap','a.txt') #重命名文件a.txt.swap为a.txt


      5、bytes模式操作文件
        以bytest模式操作文件时,读取时显示为二进制,并且只能写入二进制。
        1)以bytes模式读取文件,显示二进制
          with open('a.txt','rb') as f:
            print(f.read())
        2)以bytes模式写入文件,需要加encode
          with open('a.txt','wb') as f:
            f.write('牛牛牛'.encode('utf-8'))
        3)bytes模式常用环境
          文本的方式读不了二进制文件,硬盘上存储的都是二进制数据,除了文本之外,其它的都需要以二进制方式打开如.jpg格式。
          with open('zly.jpg','rb') as read_f,open('zly_new.jpg','wb') as write_f:
            data = read_f.read()
            write_f.write(data)

    三、补充
      1、三元表达式
        三元表达式(精简),条件成立写左边x,不成立写右边y
        正常写法:
          x = 10
          y = 2
          if x > y:
          print(x)
          else:
          print(y)
        三元表达式:result = 值1 条件 值2,如果条件成立,那么将 “值1” 赋值给result变量,否则,将“值2”赋值给result变量
          result = x if x > y else y
          print(result)

      2、文件内光标移动*
        注意:read(3)代表读取3个字符,其余的文件内光标移动都是以字节为单位如seek,tell,read,truncate
        1)read()
          with open('a.txt','r',encoding='utf-8') as f:
            print(f.read(3))
        2)seek() 参数一是位移值指从开始第第几个字符,参数二是起始位置包含0、1、2三个值,0表示文件起始位置,1表示当前位置,2表示文件结尾位置(1和2常用于rb模式)
          with open('a.txt','r',encoding='utf-8') as f:
            f.seek(0) #将光标移动到文件起始位置。
            f.seek(3) #默认情况,是以文件起始位置作为开始,往后移动3个bytes,#当前光标在第三个字节后,打印就会打印第三个字节后的内容
            f.seek(2,1) #1 代表以当前光标所在的位置为开始,往后移动2个 bytes
            f.seek(-1,2) # 2表以文件结尾位置为开始,往回移动1个 bytes, 都算一个bytes

        3)tell() ,显示当前所在的字节位置,打印3
          with open('a.txt','r',encoding='utf-8') as f:
            f.seek(3)
            print(f.tell())

        4)truncate() 截断,truncate内指定的数字代表字节,指保留从开始到指定数字。写入操作,打开文件时需要用r+ 。
          a.txt 你瞅啥 #一个汉字代表三个字节,打印前6个字节,最终结果显示 你瞅
          with open('a.txt','r+',encoding='utf-8') as f:
            f.truncate(6)

      3、for循环返回值
        对for循环执行成功后的返回值提示,如遇到break则不会执行。
        with open('a.txt','r',encoding='utf-8') as f:
          for i in f:
            print(i)
            #break
          else:
            print("执行成功!")

    四、函数
      1、函数的特点
        1)可读性高
        2)统一管理且维护成本低
        3)有组织有结构,一次定义多次调用

      2、函数的分类
        1)内置函数
          内置函数是内置在python中的,可以直接调用。
          如:sum、max、min、len等。
            b = sum([1,2])
            print(b)
        2)自定义函数
          为什么要定义函数?:先定义后使用,如果没有定义而直接使用,就相当于引用了一个不存在的变量名
          def foo():
            print('from foo')
          print(foo)

          函数的使用包含两个阶段:定义阶段和使用阶段

            语法
            def 函数名(参数1,参数2,...):
              """文档注释"""
              函数体
              return 值

            x=len('hello')
            print(x)

          函数的定义主要有如下要点:
            def:表示函数的关键字
            函数名:函数的名称,日后根据函数名调用函数
            函数体:函数中进行一系列的逻辑计算,如:发送邮件、计算出 [11,22,38,888,2]中的最大数等...
            参数:为函数体提供数据
            返回值:当函数执行完毕后,可以给调用者返回数据。

          自定义函数例:
            def print_star(): #定义函数
              print('*'*6) #函数体

            def print_msg():
              print('hello world')
          调用:
            print_star() #调用函数
            print_star()
            print_msg() #调用函数
            print_star()
            print_star()

          结果:
            ******
            ******
            hello world
            ******
            ******

      3、定义函数的形式以及调用函数
        1)无参,如果函数的功能仅仅只是执行一些操作而已,就定义成无参函数,无参函数通常都有返回值,
          def print_star():
            print('#'*6)

        2)有参函数:函数的功能的执行依赖于外部传入的参数,有参函数通常都有返回值
          def my_max(x,y):
            res=x if x >y else y
            return res
        3)调用函数,按照有参和无参可以将函数调用分两种
          def foo():
            print('from foo')

          def bar(name):
            print('bar===>',name)

          foo() #定义时无参,调用时也无需传入参数
          bar('egon') #定义时有参,调用时也必须有参数

        4)按照函数的调用形式和出现的位置分三种
          (1)调用函数的语句形式
            def foo():
              print('from foo')
            foo()
          (2)调用函数的表达式形式,xy传参乘以10000000
            def my_max(x,y):
              res=x if x >y else y
              return res

            res=my_max(1,2)*10000000
            print(res)
          (3)把函数调用当中另外一个函数的参数
            def my_max(x,y):
              res=x if x >y else y
              return res
            res=my_max(my_max(10,20),30)
            print(res)


      4、函数的返回值
        1)三种情况返回值都为None:
          没有return
          return 什么都不写
          return None
        2)return 一个值 函数调用返回的结果就是这个值
          def foo():
            print('from foo')
            x=1
            return x
          res=foo()
          print(res)
        3)return 值1,值2,值3,... 返回结果:(值1,值2,值3,...)
          def foo():
            print('from foo')
            x=1
            return 1,[2,3],(4,5),{}
          res=foo()
          print(res) #打印结果:(1,[2,3],(4,5),{})
          a,b,c,d=foo()
          print(d)
        4)序列的解压
            t=(1,2,3)
            a,b,c=t
            print(a) #打印1
            print(b) #打印2
            print(c) #打印3
          只要第一个值,其它值使用_下划线占位
            t=(1,2,3)
            a,_,_=t
            print(a) #只打印a的值1

          只要开头和结尾的值,中间使用*_占位中间所有参数
            t=(1,2,3,4,5,6)
            a,*_,c=t
            print(a,c) #只打印开头和结尾的值,执行结果打印 1 6


      5、函数的参数
        1)形参(变量名),实参(值)。
          x和y为形参(变量名),1和2为实参(值),最后执行结果打印1 2 。
          #定义阶段
            def foo(x,y): #x=1,y=2
              print(x)
              print(y)
          #调用阶段
            foo(1,2)


          详细的区分函数的参数分为五种:
          位置参数,关键字参数,默认参数,可变长参数(*args,**kwargs),命名关键字参数
        2)位置参数
          def foo(x,y,z):#位置形参:必须被传值的参数
            print(x,y,z)

          foo(1,2,3) #位置实参数:与形参一一对应

        3)关键字参数:key=value
          def foo(x,y,z):
            print(x,y,z)

          foo(z=3,x=1,y=2)

          关键字参数需要注意的问题:
            1:关键字实参必须在位置实参后面
            2: 不能重复对一个形参数传值
              foo(1,z=3,y=2) #正确
              foo(x=1,2,z=3) #错误


        4)默认参数
            def register(name,age,sex='male'): #形参:默认参数
              print(name,age,sex)
            register('asb',age=40)
          默认参数需要注意的问题:
            (1)默认参数必须跟在非默认参数后,否则在定义阶段就会报错
              def register(sex='male',name,age): #在定义阶段就会报错
                print(name,age,sex)

            (2):默认参数在定义阶段就已经赋值了,而且只在定义阶段赋值一次,最终foo(1)结果为100000000。
              a=100000000
              def foo(x,y=a):
                print(x,y)
              a=0
              foo(1)
            (3)默认参数的值通常定义成不可变类型(如元组)。

        5)可变长参数
          (1)*args,*会把溢出的按位置定义的实参都接收,以元组的形式赋值给args
            def foo(x,y,*args):
              print(x,y)
              print(args)
            foo(1,2,3,4,5)
            循环计算溢出参数:
            def add(*args):
              res=0
              for i in args:
                res+=i
              return res
            print(add(1,2,3,4))
            print(add(1,2))
          (2)**kwargs,**会把溢出的按关键字定义的实参都接收,以字典的形式赋值给kwargs
            def foo(x, y, **kwargs):
              print(x, y)
              print(kwargs)
            foo(1,2,a=1,name='egon',age=18)
            判断如果溢出参数中有if的条件,则打印实参,最后调用函数。

            def foo(name,age,**kwargs):
              print(name,age)
              if 'sex' in kwargs:
                print(kwargs['sex'])
              if 'height' in kwargs:
                print(kwargs['height'])
    
            foo('egon',18,sex='male',height='185')
            foo('egon',18,sex='male')

        6)命名关键字参数,*后定义的参数为命名关键字参数,这类参数,必须被传值,而且必须以关键字实参的形式去传值
          def foo(name,age,*,sex='male',height):
            print(name,age)
            print(sex)
            print(height)
          foo('egon',17,height='185')
        7) 补充:函数定义阶段到底干了什么事情:只检测函数体的语法,并不会执行
          def bar():
            x
            if 1 >2:
            print('====>')
          #bar()




     





     

  • 相关阅读:
    待整理
    字符编码 【ZZ】
    python中的数据类型,存储,实现
    python中的浅拷贝和深拷贝
    算法比较-SVM和logistic回归
    机器学习中的范数规则化之(一)L0、L1与L2范数
    全排列的编码和解码----康托编码
    C++的const类成员函数
    Trie树的简单描述(需后续总结)
    UWP 手绘视频创作工具技术分享系列
  • 原文地址:https://www.cnblogs.com/zhangmeixia/p/6857448.html
Copyright © 2020-2023  润新知