zoukankan      html  css  js  c++  java
  • Python基础之字符编码,文件操作流与函数

    一.字符编码

    1.字符编码的发展史

    阶段一:现代计算机起源于美国,最早诞生也是基于英文考虑的ASCII

        ASCII:一个Bytes代表一个字符(英文字符/键盘上的所有其他字符),1Bytes=8bit,8bit可以表示0-2**8-1种变化,即可以表示256个字符

        ASCII最初只用了后七位,127个数字,已经完全能够代表键盘上所有的字符了(英文字符/键盘的所有其他字符)

        后来为了将拉丁文也编码进了ASCII表,将最高位也占用了
     
    阶段二:为了满足中文,中国人定制了GBK

      GBK:2Bytes代表一个字符

      为了满足其他国家,各个国家纷纷定制了自己的编码

      日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里
     
    阶段三:各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。

      于是产生了unicode, 统一用2Bytes代表一个字符, 2**16-1=65535,可代表6万多个字符,因而兼容万国语言

      但对于通篇都是英文的文本来说,这种编码方式无疑是多了一倍的存储空间(二进制最终都是以电或者磁的方式存储到存储介质中的)

      于是产生了UTF-8,对英文字符只用1Bytes表示,对中文字符用3Bytes

    需要强调的一点是:

      unicode:简单粗暴,所有字符都是2Bytes,优点是字符->数字的转换速度快,缺点是占用空间大

      utf-8:精准,对不同的字符用不同的长度表示,优点是节省空间,缺点是:字符->数字的转换速度慢,因为每次都需要计算出字符需要多长的Bytes才能够准确表示

    2.文本编辑器存取文件的原理(notepad++,pycharm等)

      打开编辑器就启动了 一个进程,是在内存中的,所以在编辑器编写的内容也都是存放于内存中的,断电后数据丢失,因而需要保存到硬盘上。

    点击保存按钮,就从内存中把数据刷到了硬盘上。在这一点上,我们编写一个py文件(没有执行),跟编写其他文件没有任何区别,都只是在编写一堆字符而已。

    3.python解释器执行py文件的原理

      阶段一:启动python解释器
      阶段二:python解释器此时就是一个文本编辑器,负责打开文件test.py,即从硬盘中读取test.py的内容到内存中
      此时,python解释器会读取test.py的第一行内容,#coding:utf-8,来决定以什么编码格式来读入内存,这一行就是来设定python解释器这个软件的编码使用的编码格式这个编码,
      可以用sys.getdefaultencoding()查看,如果不在python文件指定头信息#-*-coding:utf-8-*-,那就使用默认的
      python2中默认使用ascii,python3中默认使用utf-8
      阶段三:读取已经加载到内存的代码(unicode编码的二进制),然后执行,执行过程中可能会开辟新的内存空间,比如x="json"
      内存的编码使用unicode,不代表内存中全都是unicode编码的二进制,
      在程序执行之前,内存中确实都是unicode编码的二进制,比如从文件中读取了一行x="json",其中的x,等号,引号,地位都一样,都是普通字符而已,都是以unicode编码的二进制形式存放与内存中的
      但是程序在执行过程中,会申请内存(与程序代码所存在的内存是俩个空间),可以存放任意编码格式的数据,比如x="json",会被python解释器识别为字符串,会申请内存空间来存放"hello",然后让x指向该内存地址,此时新申请的该内  存地址保存也是unicode编码的json,如果代码换成x="json".encode('utf-8'),那么新申请的内存空间里存放的就是utf-8编码的字符串json了

    二.文件操作

    打开文件的方式有:

    • r,只读模式(默认)
    • w,只写模式(不可读;不存在则创建;存在则删除内容;)
    • a,追加模式(可读;   不存在则创建;存在则只追加内容;)

    "+"表示可以同时读写某个文件

    • r+,可读写文件(可读;可写)
    • w+,写读文件(可写;可读)
    • a+,同a

    "b"表示处理二进制文件

    • rb
    • wb

    现有如下文件:

    飞机飞过天空 天空之城
    落雨下的黄昏的我们
    此刻我在异乡的夜里
    感觉着你忽明忽暗
    我想回到过去 沉默着欢喜
    天空之城在哭泣越来越明亮的你
    爱情不过是生活的屁
    折磨着我也折磨着你
    港岛妹妹
    你献给我的西班牙馅饼
    甜蜜地融化了我
    天空之城在哭泣
    港岛妹妹
    我们曾拥有的甜蜜的爱情
    疯狂地撕裂了我
    天空之城在哭泣
    有人路过那里 回来告诉我
    天空之城在哭泣无法呼吸的你
    此刻我在异乡的夜里
    想念着你越来越远
    

    1."r"读取文件,并将文件输出出来,encoding="utf-8"是将文件读取出来以后转换成utf-8格式,在windows下防止因为编译格式问题乱码。如果是read(4),4表示读的是字符。

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

     2."w"写入文件,将之前的文件清空后写入。

    f = open("a.txt", "w", encoding="utf-8")
    f.write("炎黄子孙")
    f.close
    

     3."a"写入文件,不清空之前的文件,将光标移到文件的最后,追加写入。

    f = open("a.txt", "a", encoding="utf-8")
    f.write("
    炎黄子孙")
    f.close()
    

     4.利用with语句来帮我们调用clese()方法,当with执行完之后,内部会自动关闭并释放文件资源。

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

     5.seek()内指定的数字代表的是字节数,以文件起始位置作为开始。

    with open("a.txt", "r", encoding="utf-8") as f:
        f.seek(3)  # 默认情况,是以文件起始位置作为开始,往后移动3个bytes
        print(f.readline()) # 读取文件第一行
    """
    输出结果:
    机飞过天空 天空之城
    """
    

     6.closed判断文件是否是关闭状态,返回True或者False

    f = open("a.txt", "r", encoding="utf-8")
    f.close()
    print(f.closed)
    """
    输出结果:
    True
    """
    

     7.encoding查看文件编码。

    f = open("a.txt", "r", encoding="utf-8")
    print(f.encoding)
    """
    输出结果:
    utf-8
    """
    

     8.name查看文件名

    f = open("a.txt", "r", encoding="utf-8")
    print(f.name)
    """
    输出结果:
    a.txt
    """
    

     9.mode指定操作模式,不指定的话默认是r模式(可以改变位置)

    f = open("a.txt", encoding="utf-8", mode ="r")
    

    10. readable判断文件是否是r模式打开,返回True或False

    f = open("a.txt", encoding="utf-8", mode ="r")
    print(f.readable())  # 判断文件是否是r模式打开
    """
    输出结果:
    True
    """
    

    11. writable判断文件是否是w模式打开,返回True或False

    f = open("a.txt", encoding="utf-8", mode ="w")
    print(f.writable()) # 判断文件是否是w模式打开
    """
    输出结果:
    True
    """xt", encoding="utf-8", mode ="w")
    

    12.readline打印一行,end是不打印换行符

    f = open("a.txt", encoding="utf-8", mode ="r")
    print(f.readline(), end="")  # readline读取一行,end是不打印换行符
    print(f.readline(), end="")
    """
    输出结果:
    飞机飞过天空 天空之城
    落雨下的黄昏的我们
    """
    

     13.文件修改

    import os
    read_f = open("a.txt", "r", encoding="utf-8")
    write_f = open("b.txt", "w", encoding="utf-8")
    for line in read_f.readlines():  # 将a.txt中的文件遍历出来
        if line.startswith("飞机飞过天空天空之城"): # 判断第一句是否是想要修改的内容
            line=("李志,天空之城
    ")
        write_f.write(line)
    read_f.close()
    write_f.close()
    os.remove("a.txt") # 将a.txt删除
    os.rename("b.txt", "a.txt") # 把b.txt改成a.txt
    

     14.文件操作,类似于日志的实时更新

    import time
    with open('access.log','r', encoding='utf-8') as f:
        f.seek(0, 2)
        while True:
            line = f.readline().strip() # 移除字符串头尾指定的字符(默认为空格)
            if line:
                print('新增一行日志:',line)
            time.sleep(0.5) # 睡眠0.5秒
    """
    输出结果:
    新增一行日志: 123456
     """
    

     15.copy图片文件

    with open('1.jpg','rb') as read_f,
            open('2.jpg','wb') as write_f:
        data=read_f.read()
        write_f.write(data)
    

    三.函数

    函数介绍:

    函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

    1.python的内置函数,如:sum,max,min等

    a = len('hello') # 打印长度
    b = max([1, 2, 3]) # 求最大值
    print(a)
    print(b)
    """
    输出结果:
    5
    3
    """
    

    定义函数: 

    1.自定义函数

    def print_star():
        print('*'*6)
    def print_msg():
        print('hello world')
    print_star()
    print_msg()
    print_star()
    """
    输出结果:
    ******
    hello world
    ******
    """
    

    2.先定义后使用。

    def foo():  # 指向内存地址
        print("from foo")
    print(foo)
    """
    输出结果:
    <function foo at 0x0000014692FB7F28>
    """
    

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

    语法

    def 函数名(参数1, 参数2,...):

      """文档注释"""

      函数体

      return 值

    4.函数定义的三种形式。

    a.无参函数:如果函数的功能仅仅执行一些操作而已,就定义成无参函数,无参函数通常都有返回值。

    def print_star():
        print('*'*6)
    

     b.定义有参函数:函数的执行依赖于外部传入的参数,有参函数通常都有返回值。

    def my_max(x,y):
        res=x if x >y else y
        return res
    

    c.空函数

    def select():
        """
        select
        """
        pass
    

    调用函数:

    1.调用无参函数,定义时无参,调用时也无需传入参数。

    def foo(): 
        print("from foo")
    foo()
    """
    输出结果:
    from foo
    """
    

     2.调用有参函数,定义时有参,调用时也必须有参。

    def bar(name):
        print("bar=====>",name)
    bar("json")
    """
    输出结果:
    bar=====> json
    """
    

    3. 调用函数的表达式形式。

    def my_max(x, y):
        res=x if x >y else y
        return res
    res = my_max(12,23)*10
    print(res)
    """
    输出结果:
    230
    """
    

     4.把函数调用,当成另外一个函数的参数,求三个数的最大值。

    def my_max(x, y):
        res=x if x >y else y
        return res
    res = my_max(my_max(9,5), 80)
    # res = my_max(12,23)*10
    print(res)
    """
    输出结果:
    80
    """
    

    函数的返回值:

    1.不写return,python默认返回None

    def foo():
        print("from foo")
    res = foo()
    print(res)
    """
    以下三种情况返回都是None:
    没有 return
    return 后边什么都不写
    return None
    """
    

    2.return一个值,函数调用返回的结果,也是这个值。

    def foo():
        print("from foo")
        x = 1
        return x
    res = foo()
    print(res)
    """
    输出结果:
    1
    """
    

    3.return 值1,值2,值3...返回的是一个元组形式。

    def foo():
        print("from foo")
        return 1, [1, 2, 3], (1, 2, 3),{}
    res = foo()
    print(res)
    """
    输出结果:
    (1, [1, 2, 3], (1, 2, 3), {})
    """
    

    函数参数:

    详细的分函数的参数有五种:

    位置参数,关键字参数,默认参数,可变长参数(*args,  **kwargs),命名关键字参数。

    a.位置参数

    def foo(x ,y): # 位置形参,必须必须被传值的参数
        print(x, y)
    foo(1, 2) # 位置实参,与形参一一对应
    """
    输出结果:
    1 2
    """
    

     b.关键字参数key=value。

    关键字参数需要注意的问题:

    1.关键字实参必须在位置实参后边,

    2.不允许对一个形参重复传值。

    def foo(a ,b, c): 
        print(a ,b, c)
    foo(c=1,b=2,a=3) 
    """
    输出结果:
    3 2 1
    """
    

     c.默认参数

    默认参数需要注意的问题:

    1.默认参数必须在非默认参数后,

    2.默认参数在定义阶段就已经赋值了,而且只能在定义阶段赋值一次,

    3.默认参数的值通常定义成不可变类型。

    def register(name,age,sex='male'): #形参:默认参数
        print(name,age,sex)
    
    register('a', age=18)
    register('a1', 28)
    register('a2', 30)
    register('a3', 29)
    
    register('钢蛋', 20, 'female')
    register('钢蛋', sex='female', age=19)
    
    """
    a 18 male
    a1 28 male
    a2 30 male
    a3 29 male
    钢蛋 20 female
    钢蛋 19 female
    """
    

     d.可变长参数

    ①*args

    def foo(x,y,*args): #*会把溢出的按位置定义的实参都接收,以元组的形式赋值给args
        print(x,y)
        print(args)
    foo(1, 2, 3, 4, 5)
    
    """
    1 2
    (3, 4, 5)
    
    """
    

     ②**kwargs

    def foo(x, y, **kwargs):  # **会把溢出的按关键字定义的实参都接收,以字典的形式赋值给kwargs
        print(x, y)
        print(kwargs)
    foo(1,2,a=1,name='egon',age=18)
    """
    1 2
    {'name': 'egon', 'age': 18, 'a': 1}
    """
    
  • 相关阅读:
    问题 G: 艰难取舍(dp)
    算式
    问题 G: 背菜谱
    问题 B: 寻路
    问题 D: 数字变换(dfs)
    问题 D: 2的幂数
    问题 C: 幸运数字II(4,7)
    问题 D: 莱布尼茨三角形
    问题 E: 有理数树
    2020年秋高级软件工程”领跑衫“获奖感言
  • 原文地址:https://www.cnblogs.com/Crazy-lyl/p/6854534.html
Copyright © 2011-2022 走看看