• python基础-文件处理与函数


    1. 文件处理

    1.1 文件处理流程

      1.打开文件,得到文件句柄并赋值给一个变量

      2.通过句柄对文件进行操作

      3.关闭文件

    1.2 文件读取模式r

      r文本模式的读,在文件不存在,不会创建新文件

    f = open('a.txt','r',encoding='utf-8')
    f.readable()    # 判读文件是否可读
    f.writable()    # 判读文件是否可写
    f.readline()    # 一次读取一行
    f.readlines()   # 一次读取所有值
    f.close() 

    1.3 文件读取模式rb

      b模式直接从硬盘中读取bytes,不用指定编码格式;以什么格式存的文件,以什么格式读取文件

    f = open('a.txt','rb')
    print(f.read().decode('utf-8'))
    f.close() 

    1.4 文本写模式 w

      w文本模式的写,文件存在则清空,不存在则创建

    f = open('a.txt','w',encoding='utf-8')
    f.writable()                    # 判断是否可写
    f.readable()                    # 判断是否可读
    f.write('你好')                 # 写单个值
    f.writelines(['aaa
    ','bbb
    '])    # 写列表
    f.writelines(('111
    ','222
    '))    # 写元组
    f.close() 

    1.5 文件追加模式a

      a 文件模式的追加,文件存在、光标跳到文件末尾,文件不存在创建

    f = open('a.txt','a',encoding='utf-8')
    print(f.tell())     # 打印文件光标的位置
    f.write('3333
    ')
    f.write('4444
    ')
    f.close()

    1.6 混合模式

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

      r+     可读写文件,即可读、可写、可追加

      w+    可写读文件,即可写、可读、可追加

      a+     同a

      混合模式不常用,了解即可。

    1.7 b模式

    #rb模式直接从硬盘中读取bytes
    f = open('a.txt','rb')
    print(f.read())
    f.close()
    
    #wb模式
    f = open('a.txt','wb')
    f.write('你好'.encode('utf-8'))
    f.close() 

    1.8 遍历文件

      在内存中,同时只有一条内容,不依赖索引;文件很多,用循环遍历的方式读取文件。

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

    1.9 Copy文件

      利用r模式,模拟Copy动作;以b的方式打开文件,不会涉及文件编码的问题,b是Bytes的格式;利用r进行处理文件路径,以后经常需要处理文件路径的问题,也就是右斜杠没有特殊意义。

    import sys
    
    if len(sys.argv) < 3:
        print('Usage:python3 copy.py source.file target.file')
        sys.exit()
    
    with open(r'%s' %sys.argv[1],'rb') as f_read,
        open(r'%s' %sys.argv[2],'wb') as f_write:
        for line in f_read:
            f_write.write(line)

    1.10 文件其他操作

    1.10.1 read

      例如:read(3)

      1.文件打开方式为文本模式时,代表只读取3个字符。

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

      2.文件打开方式为b模式时,代表读取3个字节。

    f = open('a.txt','rb')
    print(f.read(6).decode('utf-8'))
    print(f.read(3).decode('utf-8'))
    f.close() 

    1.10.2 seak

      以字节为单位,进行移动光标,有三种模式,三种模式默认指定的参照物不同;其中1、2模式必须在b模式下进行。

      0模式:默认以文件开头为光标移动,参照物为文件开头

      1模式:以当前光标所在的位置为参照物

      2模式:以文件结尾为参照物,进行文件光标的移动

    # seek的0模式 默认为0模式
    f = open('a.txt','r')
    print(f.read(3))
    print(f.tell())
    f.seek(3)
    print(f.tell())
    print(f.read())
    
    # seek的1模式
    f = open('a.txt','rb')
    print(f.read(3))
    print(f.tell())
    f.seek(3,1)
    print(f.tell())
    print(f.read().decode('utf-8'))
    
    # seek的2模式
    f=open('a.txt','rb')
    f.seek(0,2)
    print(f.tell())
    print(f.read())

    1.10.3 tell

      tell是告诉光标的位置,tell编译器的具体实现:

    def tell(self, *args, **kwargs): # real signature unknown
        """
        Current file position.
        
        Can raise OSError for non seekable files.
        """
        pass 

    1.10.4 truncate

      truncate是截断文件,所以文件的打开方式必须可写,但是不能用w、w+等方式打开,因为那样直接清空文件,所以truncate要在r+、a、a+等模式使用;

    with open('a.txt','r+',encoding='utf-8') as f:
        f.truncate(2) 

    1.10.5 类似于tail命令

      以rb方式打开文件,光标移动到最后:f.seek(0,2)

    # tail.py -f access.log
    import time
    import sys
    
    with open(r'%s' % sys.argv[2], 'rb') as f:
        f.seek(0, 2)
        while True:
            line = f.readline()
            if line:
                print(line.decode('utf-8'),end='')
            else:
                time.sleep(0.5) 

    1.11 总结

             最常用的模式:r、w、a

                                      rb、wb、ab

             文件的其他模式,了解即可

    2.函数

    2.1 不用函数的问题

             复杂度增大

             组织结构不清晰

             可读性差

             代码冗余

             可扩展性差

        如何解决问题:

               利用函数进行解决问题。例如修改下水道的问题:需要准备工具;利用工具与函数进行类比:

               1.工具就是具备某一种功能的物件,就是程序中的函数的概念

               2.事先准备工具的过程称为函数的定义

               3.遇到特定的场景拿来就用称为函数的调用

    2.2 函数的分类

      在python中,函数的分类有两种:

      1. 内置函数

      2. 自定义函数

        例如:python内置的函数(len、print、max)

    2.3 原则

      函数的使用原则:

      1.先定义

               2.再调用

    2.4 直观感受使用函数

    '''
    **********************
    hello jack
    **********************
    '''
    
    def print_star():
        print('*'*20)
    
    def print_msg():
        print('hello jack')
    
    print_star()
    print_msg()
    print_star() 

    2.5 函数使用

      函数的定义与变量的定义类似,没有事先定义变量,而直接引用变量,会报错

      没有事先定义函数,而直接调用,就相当于在引用一个不存在的变量名

    '''
    函数的使用:
        1 先定义
        2 再调用
    '''
    
    #定义阶段
    def foo():
        print('from foo')
        bar()
    def bar():
        print('from bar')
    
    #调用阶段
    foo()

      函数在定义阶段发生了什么事情??

      函数在定义阶段:只检测语法,不执行代码

    def func():
         asdf #asdf=’bbbb’
    func()

    2.6 函数定义

    #函数的定义语法
    '''
    def 函数名(arg1,arg2,arg3):
        "注释"
        函数体
        return 返回值
    
    函数名一般是动词
    参数
    return:函数内部可以有多个return,但只能执行一次,函数就结束调用,
            并且会把return后的值作为函数执行的结果返回
    ''' 

    2.6.1函数定义三种形式

      无参:     应用场景仅仅只是执行一些操作,比如与用户交互,打印

      有参:     需要根据外部传进来的参数,才能执行相应的逻辑,比如统计长度,求最大值

      空函数:设计代码结构

    2.6.2 无参函数

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

    2.6.3 有参函数

    # 求最大值的函数,类似于python内置函数max
    def my_max(x,y):
        if x > y:
            return x
        else:
            return y
    
    res=my_max(1,2)
    print(res) 

    2.6.4 空函数

    # sql解析,首先设计sql解析框架
    def select(sql):
        '''select function'''
        print(sql)
        #sql=['select', '*', 'from', 'mysql.user;']
    
    def insert(sql):
        '''insert function'''
        pass
    
    def update(sql):
        '''update function'''
        pass
    
    def delete(sql):
        '''delete function'''
        pass
    
    #select  * from mysql.user;
    def main():
        while True:
            sql=input('>>: ').strip()
            if not sql:continue
            cmd_info=sql.split()
            cmd=cmd_info[0]
    
            if cmd == 'select':
                select(cmd_info)
    
    main() 

    2.7 函数return

      return,是函数结束的标志

      return的返回值没有类型限制

        1. 没有return:返回None,等同于return None

        2. return 一个值:返回该值

        3. return val1,val2,val3:返回(val1,val2,val3)

      需要返回值:

        调用函数,经过一系列的操作,最后得到一个确定的结果,则必须要有返回值

        通常有参函数要有返回值,输入参数,经过计算,得到一个最终结果

        不需要返回值:

        调用函数,仅仅只是执行一系列的操作,最后不需要得到结果,无序有返回值

        通常无参函数不需要有返回值

    #函数的返回值,返回多个值
    def func():
        print('from func')
        return [1,2,3],'a',1,{'a':3}

    2.8 函数调用

      函数的调用,有三种形式:

        1.语句形式

        2.表达式形式

        3.函数调用当做另一个函数的参数

    def my_max(x,y):
        if x > y:
            return x
        else:
            return y
    
    my_max(1,2)                 # 语句形式
    res=my_max(1,2)*10             # 表达式形式
    res2=my_max(my_max(1,2),3)     # 函数调用可以当做另外一个函数的参数 

    2.9 函数参数

      函数的参数,分两种

               1.形参:在定义函数时,括号内的参数,形参就是变量名

               2.实参:在调用函数时,括号内的参数,实参就是变量值

      在调用阶段实参(变量值)才会绑定形参(变量名),调用结束,解除绑定

    #形参:在定义函数时,括号内的参数成为形参
    #特点:形参就是变量名
    def foo(x,y): #x=1,y=2
        print(x)
        print(y)
    
    #实参:在调用函数时,括号内的参数成为实参
    #特点:实参就是变量值
    foo(1,2)
    
    #在调用阶段实参(变量值)才会绑定形参(变量名)
    #调用结束后,解除绑定 

    2.10 参数分类

    2.10.1 位置参数

      位置参数:按照从左到右的顺序依次定义的参数

        1.位置形参:必须被传值,并且多一个不行,少一个也不行

        2.位置实参:与形参按照位置一一对应

    def foo(x,y):
        print(x)
        print(y)
    foo(1,2)
    
    def register(name,age):
        print(name)
        print(age)
    register('jack',18) 

    2.10.2 关键字参数

      关键字实参:指的是按照name=value的形式,指名道姓地给name传值

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

        问题一:语法规定位置实参必须在关键字实参的前面

        问题二:一定不要对同一个形参传多次值

    def foo(name,age):
        print(name)
        print(age)
    foo(age=18,name='jack')
    
    #关键字实参需要注意的问题是:
    def foo(name,age,sex):
        print(name)
        print(age)
        print(sex)
    
    # 正常传值
    foo('jack',18,'male')
    foo(sex='male',age=18,name='jack')
    foo('jack',sex='male',age=18)
    
    #问题一:语法规定位置实参必须在关键字实参的前面
    foo('jack',sex='male',age=18)
    
    #问题二:一定不要对同一个形参传多次值
    foo('jack',sex='male',age=18,name='jack1')
    foo('male',age=18,name='jack1')

    2.10.3 默认参数

      默认参数,即默认形参:在定义阶段,就已经为形参赋值,意味在调用阶段可以不用传值

      使用默认参数,可以降低函数使用的复杂度。

    def foo(x,y=222):
        print(x)
        print(y)
    
    foo('jack')
    foo(1,'a')
    
    def register(name,age,sex='male'):
        print(name,age,sex)
    
    register('jack',73)
    register('tom',38)
    register('mary',28,'female')

      默认参数需要注意的问题

      问题一:默认参数必须放在位置参数之后

    def foo(y=1, x):
        print(x, y) 

      问题二:默认参数只在定义阶段赋值一次,而且仅一次

    x=100
    def foo(a,b=x):
         print(a,b)
    
    x=22222
    foo('jack') 

      问题三:默认参数的值应该定义成不可变类型

        不可变类型:包括字符串、数字、元组

        可变类型:     列表、字典

    2.11 可变长参数

      可变长参数指的是实参的个数不固定(个数多了)

      实参无非位置实参和关键字实参两种

      形参必须要两种机制分别处理:

        按照位置定义的实参溢出的情况         *

        按照关键字定义的实参溢出的情况     **

    2.11.1 位置参数

      多出来的位置实参,会交给*处理,保存成元组的形式,*把多出来赋值给args

    def foo(x,y,*args): #args=(3,4,5,6,7)
        print(x)
        print(y)
        print(args)
    
    foo(1,2,3,4,5,6,7) #*
    foo(1,2) #*

      *args的扩展用法

      * 处理的是位置参数

      * 可以存在于形参位置,*也可以在于实参位置

      碰到*位于实参位置,打回原形,拆成位置参数

      例如:foo(1,2,*(3,4,5,6,7))  <====>  foo(1,2,3,4,5,6,7)

    def foo(x,y,*args): # *args = *(3,4,5,6,7)
        print(x)
        print(y)
        print(args)
    foo(1,2,3,4,5,6,7) # *
    foo(1,2,*(3,4,5,6,7))  # 等价于foo(1,2,3,4,5,6,7)
    
    def foo(x,y,*args): #
        print(x)
        print(y)
        print(args)
    foo('a','b',*(1,2,3,4,5,6,7))     # 等价于foo('a','b',1,2,3,4,5,6,7)
    foo('jack',10,2,3,4,5,6,9) 

    2.11.2 关键字参数

      多出来的关键字实参,会交给**处理,保存成字典形式,**把多出来的参数交给kwargs

    def foo(x,y,**kwargs): #kwargs={'z':3,'b':2,'a':1}
        print(x)
        print(y)
        print(kwargs)
    foo(1,2,z=3,a=1,b=2) #** 

      **kwargs的扩展用法

      ** 处理的是关键字参数

      ** 可以存在于形参位置,**也可以在于实参位置

      碰到**位于实参位置,打回原形,拆成关键字参数

      例如:foo(1,2,**{'z':3,'b':2,'a':1})  <====>  foo(1,2,a=1,z=3,b=2)

    def foo(x,y,**kwargs): # kwargs={'z':3,'b':2,'a':1}
        print(x)
        print(y)
        print(kwargs)
    foo(1,2,**{'z':3,'b':2,'a':1}) # foo(1,2,a=1,z=3,b=2)
    
    def foo(x, y):
        print(x)
        print(y)
    foo(**{'y':1,'x':2})  # foo(y=1,x=2) 

    2.11.3 混合使用

    def foo(x,*args,**kwargs): # args=(2,3,4,5) kwargs={'b':1,'a':2}
        print(x)
        print(args)
        print(kwargs)
    foo(1,2,3,4,5,b=1,a=2)

    2.11.4 间接调用函数

    import time
    
    def register(name,age,sex='male'):
        print(name)
        print(age)
        print(sex)
        time.sleep(3)
    
    def wrapper(*args, **kwargs): #args=('egon',) kwargs={'age':18}
        start_time=time.time()
        register(*args, **kwargs)
        stop_time=time.time()
        print('run time is %s' %(stop_time-start_time))
    
    wrapper('jack',age=26)
    register('jack',26) 

    2.11.5 命名关键字参数

      命名关键字参数,必须是被以关键字实参的形式传值

      在*后面定义的形参称为命名关键字参数,必须是被以关键字实参的形式传值;属于了解内容。

    def foo(*args,x):
        print(x)
        print(args)
    
    foo(1,2,3,4,x='jack')
    
    def foo(name,age,*,sex,group):
        print(name,age,sex,group)
    foo('jack',18,group='group1',sex='male')
    
    def foo(name,age,*,sex='male',group):
        print(name,age,sex,group)
    foo('mary',18,group='group1') 

    2.12 函数对象

      函数是第一类对象:指的是函数可以被当做数据传递

      1 被赋值

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

      2 可以当做参数传入

    def wrapper(func):
        # print(func)
        func()
    wrapper(foo) 

      3 可以当做函数的返回

    def wrapper(func):
        return func
    res=wrapper(foo)
    print(res) 

      4 可以当做容器类型的元素

    cmd_dic={
        'func':foo
    }
    
    print(cmd_dic)
    cmd_dic['func']() 
  • 相关阅读:
    猫眼电影面试经历
    北京市-钟鼓楼
    vipkid 面试经历
    转转面试经历
    二维数组中的查找
    不用除法来实现两个正整数的除法
    牛客网面试经历
    9. Palindrome Number
    Spring 简介
    mysql8 安装配置教程
  • 原文地址:https://www.cnblogs.com/goodshipeng/p/7215330.html
Copyright © 2020-2023  润新知