• Python编程-编码、文件处理、函数


    一、字符编码补充知识点

    1.文本编辑器存取文件的原理(nodepad++,pycharm,word)

    打开编辑器就打开了启动了一个进程,是在内存中的,所以在编辑器编写的内容也都是存放与内存中的,断电后数据丢失
    因而需要保存到硬盘上,点击保存按钮,就从内存中把数据刷到了硬盘上。
    在这一点上,我们编写一个py文件(没有执行),跟编写其他文件没有任何区别,都只是在编写一堆字符而已。

    2.python解释器执行py文件的原理 ,例如python test.py

    第一阶段:python解释器启动,此时就相当于启动了一个文本编辑器
    第二阶段:python解释器相当于文本编辑器,去打开test.py文件,从硬盘上将test.py的文件内容读入到内存中
    第三阶段:python解释器解释执行刚刚加载到内存中test.py的代码

    总结:

    (1)python解释器是解释执行文件内容的,因而python解释器具备读py文件的功能,这一点与文本编辑器一样
    (2)与文本编辑器不一样的地方在于,python解释器不仅可以读文件内容,还可以执行文件内容

    3.python2和python3的区别

    (1)在python2中有两种字符串类型str和unicode
    (2)在python三种也有两种字符串类型str和bytes

    4.encode和decode

    字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码。

    decode的作用是将其他编码的字符串转换成unicode编码,如str1.decode('gb2312'),表示将gb2312编码的字符串str1转换成unicode编码。
    encode的作用是将unicode编码转换成其他编码的字符串,如str2.encode('gb2312'),表示将unicode编码的字符串str2转换成gb2312编码。

    二、文件处理

    1.文件处理流程

    (1)打开文件,得到文件句柄并赋值给一个变量
    (2)通过句柄对文件进行操作
    (3)关闭文件
    示例:

    f = open('chenli.txt') #打开文件
    first_line = f.readline()
    print('first line:',first_line) #读一行
    print('我是分隔线'.center(50,'-'))
    data = f.read()# 读取剩下的所有内容,文件大时不要用
    print(data) #打印读取内容
    f.close() #关闭文件
    

    正确的打开方式

    不指定打开编码,默认使用操作系统的编码,windows为gbk,linux为utf-8,与解释器编码无关
    f=open('chenli.txt',encoding='gbk') #在windows中默认使用的也是gbk编码,此时不指定编码也行
    f.read()
    

    2.文件打开方式

    语法:
    文件句柄 = open('文件路径', mode='模式')
    打开文件的模式有:

    • r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】
    • w,只写模式【不可读;不存在则创建;存在则清空内容】
    • a, 追加模式【可读; 不存在则创建;存在则只追加内容】

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

    • r+, 读写【可读,可写】
    • w+,写读【可读,可写】
    • a+, 写读【可读,可写】

    "b"表示以字节的方式操作

    • rb 或 r+b
    • wb 或 w+b
    • ab 或 a+b

    注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码

    3.文件处理示例

    (1)上下文管理

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

    (2)以字节码方式打开文件时的操作

    with open('a.txt','rb') as f:
        print(f.read().decode('utf-8'))
    
    with open('c.txt','wb') as f:
        f.write('哈哈哈'.encode('utf-8'))
    
    (3)文本的方式读不了二进制文件
    f=open('sb.jpg','r',encoding='utf-8')
    print(f.read())
    

    (4)读取多个文件时的书写格式

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

    (5)文件操作技巧

    seek(offset,where): where=0从起始位置移动,1从当前位置移动,2从结束位置移动。当有换行时,会被换行截断。seek()无返回值,故值为None。
    tell(): 文件的当前位置,即tell是获得文件指针位置,受seek、readline、read、readlines影响,不受truncate影响
    truncate(n): 从文件的首行首字符开始截断,截断文件为n个字符;无n表示从当前位置起截断;截断之后n后面的所有字符被删除。其中win下的换行代表2个字符大小。
    readline(n):读入若干行,n表示读入的最长字节数。其中读取的开始位置为tell()+1。当n为空时,默认只读当前行的内容
    readlines读入所有行内容
    read读入所有行内容

    • 数字指的是读的是字符
    with open('a.txt','r',encoding='utf-8') as f:
        print(f.read(4)) 
    
    with open('a.txt','rb') as f:
        print(f.read(1))
    
    • seek内指定的数字代表字节
    • tell指定当前光标所在的位置
    with open('a.txt','r',encoding='utf-8') as f:
        f.seek(3)
        print(f.tell())
        print(f.read())
    
    with open('aa.txt','r+',encoding='utf-8') as f:
        # f.seek(3)
        # print(f.read())
        f.truncate(1)  #从文件的首行首字符开始截断,截断文件为n个字符
    
    • seek的使用方式
    with open('b.txt','rb') as f:
        f.read()
        f.seek(3) #默认情况,是以文件起始位置作为开始,往后移动3个bytes
        f.read(1)
        print(f.tell())
        f.seek(2,1) # 1 代表以当前光标所在的位置为开始,往后移动2个bytes
        print(f.tell())
    
        f.seek(-1,2) # 2 代表以结束光标所在的位置为开始,往后移动2个bytes
        print(f.tell())
    
        f.seek(0,2)
    
    with open('c.txt','r',encoding='utf-8') as f:
        f.seek(0,2)
        print('====>',f.read())
    

    补充知识:

    (1)tail命令的输出方式

    tail -f access.log
    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)
    

    (2)for循环结合else的用法

    当for循环不被break打断,就会执行else的代码
    for i in range(3):
        print(i)
        # continue
        if i == 1:
            break
    else:
        print('=============>') 
    
    with open('a.txt','r',encoding='utf-8') as read_f,
            open('aa.txt','w',encoding='utf-8') as write_f:
    
        for line in read_f:
            write_f.write(line)
        else:
            print('write successfull')
    
    i=0
    while i< 5:
        print(i)
        i+=1
        if i == 3:
            break
    else:
        print('------>')
    

    三、函数

    1.没有函数会有什么问题?

    (1)无组织无结构,代码冗余
    (2)可读性差
    (3)无法统一管理且维护成本高

    2.函数和过程

    过程定义:过程就是简单特殊没有返回值的函数
    当一个函数/过程没有使用return显示的定义返回值时,python解释器会隐式的返回None,所以在python中即便是过程也可以算作函数。

    def test01():
        pass
    
    def test02():
        return 0
    
    def test03():
        return 0, 10, 'hello', ['alex', 'lb'], {'WuDaLang': 'lb'}
    
    t1 = test01()
    t2 = test02()
    t3 = test03()
    
    print('from test01 return is [%s]: ' % type(t1), t1)
    print('from test02 return is [%s]: ' % type(t2), t2)
    print('from test03 return is [%s]: ' % type(t3), t3)
    
    运行结果:
    from test01 return is [<class 'NoneType'>]:  None
    from test02 return is [<class 'int'>]:  0
    from test03 return is [<class 'tuple'>]:  (0, 10, 'hello', ['alex', 'lb'], {'WuDaLang': 'lb'})
    

    3.函数分类

    (1)内置函数
    sum
    max
    min

    a=len('hello')
    print(a)
    
    b=max([1,2,3])
    print(b)
    

    (2)自定义函数

    def print_star():
        print('#'*6)
    
    def print_msg():
        print('hello world')
    
    print_star()
    print_msg()
    print_star()
    
    运行结果:
    ######
    hello world
    ######
    

    4.定义函数

    (1)为什么要定义函数?
    先定义后使用,如果没有定义而直接使用,就相当于引用了一个不存在的变量名。

    foo()
    def foo():
         print('from foo')
    print(foo)
    

    函数定义阶段到底干了什么事情:只检测函数体的语法,并不会执行

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

    def 函数名(参数1,参数2,...):
        """文档注释"""
        函数体
        return 值
    
    x=len('hello')
    print(x)
    

    (3)定义函数的三种形式

    • 无参数函数
      如果函数的功能仅仅只是执行一些操作而已,就定义成无参函数,无参函数通常都有返回值
    def print_star():
        print('#'*6)
    
    • 有参函数
      函数的功能的执行依赖于外部传入的参数,有参函数通常都有返回值
    def my_max(x,y):
    	res=x if x >y else y
    	return res
    
    • 空函数
    def auth():
        """认证功能"""
        pass
    auth()
    

    5.函数参数

    (1)函数的参数分类
    形参(变量名),实参(值)

    • 形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量
    • 实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值

    (2)详细的区分函数的参数(五类)
    1)位置参数

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

    2)关键字参数:key=value

    def foo(x,y,z):
        print(x,y,z)
    
    foo(z=3,x=1,y=2)
    
    关键字参数需要注意的问题:

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

    3)默认参数

    def register(name,age,sex='male'): #形参:默认参数
        print(name,age,sex)
    
    register('asb',age=40)
    register('a1sb',39)
    register('a2sb',30)
    register('a3sb',29)
    
    register('钢蛋',20,'female')
    register('钢蛋',sex='female',age=19)
    
    默认参数需要注意的问题:
    • 默认参数必须跟在非默认参数后
    def register(sex='male',name,age): #在定义阶段就会报错
        print(name,age,sex)
    
    • 默认参数在定义阶段就已经赋值了,而且只在定义阶段赋值一次
    a=100000000
    def foo(x,y=a):
        print(x,y)
    a=0
    foo(1)
    
    • 默认参数的值通常定义成不可变类型

    4)可变长参数
    第一种:*args

    *会把溢出的按位置定义的实参都接收,以元组的形式赋值给args

    def foo(x,y,*args): 
        print(x,y)
        print(args)
    foo(1,2,3,4,5)
    
    运行结果:
    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))
    
    运行结果:
    10
    3
    

    第二种:**kwargs

    **会把溢出的按关键字定义的实参都接收,以字典的形式赋值给kwargs

    def foo(x, y, **kwargs): 
        print(x, y)
        print(kwargs)
    foo(1,2,a=1,name='egon',age=18)
    
    运行结果:
    1 2
    {'a': 1, 'name': 'egon', 'age': 18}
    
    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')
    
    运行结果:
    egon 18
    male
    185
    egon 18
    male
    

    5)命名关键字参数

    *后定义的参数为命名关键字参数,这类参数,必须被传值,而且必须以关键字实参的形式去传值

    def foo(name,age,*,sex='male',height):
        print(name,age)
        print(sex)
        print(height)
    
    foo('egon',17,height='185')
    
    运行结果:
    egon 17
    male
    185
    

    6.综合使用

    def foo(name,age=10,*args,sex='male',height,**kwargs):
        print(name)
        print(age)
        print(args)
        print(sex)
        print(height)
        print(kwargs)
    
    foo('alex',1,2,3,4,5,sex='female',height='150',a=1,b=2,c=3)
    
    运行结果:
    alex
    1
    (2, 3, 4, 5)
    female
    150
    {'a': 1, 'c': 3, 'b': 2}
    
    def foo(*args):
        print(args)
    
    foo(1,2,3,4)
    
    *['A','B','C','D'],=====>'A','B','C','D'
    foo(*['A','B','C','D']) #foo('A','B','C','D')
    foo(['A','B','C','D'])
    
    def foo(x,y,z):
        print(x,y,z)
    
    # foo(*[1,2,3]) #foo(1,2,3)
    foo(*[1,2]) #foo(1,2)
    
    def foo(**kwargs):
        print(kwargs)
    
    #x=1,y=2  <====>**{'y': 2, 'x': 1}
    # foo(x=1,y=2)
    foo(**{'y': 2, 'x': 1,'a':1}) #foo(a=1,y=2,x=1)
    
    def foo(x,y,z):
        print(x,y,z)
    
    # foo(**{'z':3,'x':1,'y':2}) #foo(x=1,z=3,y=2)
    foo(**{'z':3,'x':1}) #foo(x=1,z=3)
    
    def foo(x,y,z):
        print('from foo',x,y,z)
    
    def wrapper(*args,**kwargs):
        print(args)
        print(kwargs)
    
    wrapper(1,2,3,a=1,b=2)
    
    def foo(x,y,z):
        print('from foo',x,y,z)
    def wrapper(*args,**kwargs):
        print(args) #args=(1,2,3)
        print(kwargs) #kwargs={'a':1,'b':2}
        foo(*args,**kwargs) #foo(*(1,2,3),**{'a':1,'b':2}) #foo(1,2,3,b=2,a=1)
    # wrapper(1,2,3,a=1,b=2)
    wrapper(1,z=2,y=3)
    
    def foo(x,y,z):
        print('from foo',x,y,z)
    def wrapper(*args,**kwargs):
        # print(args) #args=(1,)
        # print(kwargs) #kwargs={'y':3,'z':2}
        foo(*args,**kwargs) #foo(*(1,),**{'y':3,'z':2}) #foo(1,z=2,y=3)
    # wrapper(1,2,3,a=1,b=2)
    wrapper(1,z=2,y=3)
    

    7.函数的返回值

    def foo():
        print('from foo')
        return None
    res=foo()
    print(res)
    
    运行结果:
    from foo
    None
    
    以下三种情况返回值都为None:

    (1)没有return
    (2)return 什么都不写
    (3)return None

    return为一个值时,函数调用返回的结果就是这个值

    def foo():
        print('from foo')
        x=1
        return x
    res=foo()
    print(res)
    
    运行结果:
    from foo
    1
    

    return 值1,值2,值3,... 返回结果:(值1,值2,值3,...)

    def foo():
        print('from foo')
        x=1
        return 1,[2,3],(4,5),{}
    res=foo()
    print(res)
    a,b,c,d=foo()
    print(d)
    
    运行结果:
    from foo
    (1, [2, 3], (4, 5), {})
    from foo
    {}
    

    参数取值

    t=(1,2,3)
    a,_,_=t
    print(a)
    
    t=(1,2,3,4,5,6,7,8,9)
    a,*_,c=t
    print(a)
    print(c)
    
    运行结果:
    1
    1
    9
    

    8.函数调用

    • 按照有参和无参可以将函数调用分两种
      foo() #定义时无参,调用时也无需传入参数
      bar('egon') #定义时有参,调用时也必须有参数
    def foo():
        print('from foo')
    
    def bar(name):
        print('bar===>',name)
    
    • 按照函数的调用形式和出现的位置,分三种
    #调用函数的语句形式
    foo()
    #调用函数的表达式形式
    def my_max(x,y):
        res=x if x >y else y
        return res
    
    res=my_max(1,2)*10000000
    print(res)
    #把函数调用当中另外一个函数的参数
    res=my_max(my_max(10,20),30)
    print(res)
    
  • 相关阅读:
    Core上传图片
    Pytho学习(3)——注释
    zabbix实操随笔
    1900型USB接口扫描枪设置虚拟串口模式提升扫描速度
    SQLServer设置单用户
    入门安装环境
    centos下载
    java学习资料
    错误模块名称: KERNELBASE.dll
    iis部署WebService出现"因 URL 意外地以 结束,请求格式无法识别"的解决方法
  • 原文地址:https://www.cnblogs.com/tongxiaoda/p/7595703.html
Copyright © 2020-2023  润新知