• 文件操作及函数


    文件处理

    f = open(‘a.txt’,’r’)  
    f.read()

    open是在打开一个文件,是在哪里发起的请求?是在.py文件里面发起的,是自己写的应用程序,应用程序能直接操作硬件吗?所以这一步是在向操作系统发起一个请求,是不是要打开一个文件

    打开一个文件,最后赋值给f,这个f被应用程序的内存拿着,其实就是python变量的赋值操作,但是不仅仅拿到了f,操作系统还打开了一个文件对应着,用户可以直接拿着f,用f.read()执行读操作,这是系统调用,向操作系统发起了请求,正好对应操作系统打开的文件,操作系统接到read指令后,会到硬盘上读内容,然后返回给程序

    字符编码

        什么是字符编码
            把人类的字符翻译成计算机能认识的数字
        什么是字符编码表
            就是一张字符与数字对应关系的表
            Ascii
            Gbk
            Utf-8
            Unicode

        Unicode-->encode(‘utf-8’)-->bytes
        Bytes---->decode(‘utf-8’)---->unicode

    内存用的都是unicode,为的是保证速度,硬盘用utf-8,用gbk都行,为的是存储容量越小越好

    原则:
        字符以什么格式编码的就要以什么格式解码

    补充:

    写程序和编辑普通文件没有什么区别,最后保存在硬盘上,运行是交给cpu运行,
    硬盘如何让cpu去运行呢?首先要把文件中的内容整体先加载到内存中,再谈执行的问题
    那么硬盘中以utf-8编码的往内存中里面走,应该是解码成unicode.

    python3中的字符串分为两种
    x='egon' 存成unicode
    y=x.encode('utf-8') 存成bytes
    ----------------------------------
    python2中的字符串也分为两种
    x = u'egon' 与python3中的字符串一样
    y = 'alex' 与python3的bytes一样
    #r文本模式的读,在文件不存在时,不会创建新文件
    f=open('a.txt','r',encoding='utf-8')
    print(f.read())
    print(f.readline())
    print(f.readlines()) f.close()
    #rb模式即直接从硬盘中读取bytes f=open('a.txt','rb') # 因为是直接从硬盘中读取的二进制,所以不需要encoding print(f.read()) #b'xe4xbdxa0xe5xa5xbdxe5x95x8aalex' print(f.read().decode('utf-8')) #你好啊

    #wb模式
    f=open('a.txt','wb')
    #f.write('你好啊') #会报错
    f.write('你好啊'.encode('utf-8'))
    # Python3的字符串是unicode类型,unicode转为bytes需要encode
    
    
    #python3 copy.py a.jpg  b.jpg     拷贝文件,文本文件(字符编码),非文本文件(编码有问题,所以只能采取二进制模式拷贝文件)。采用二进制,无论什么格式,都不会乱码
    ---------------------------------------------
    import sys
    
    #python copy.py source.file target.file
    # print(sys.argv)
    # sys.exit()
    
    if len(sys.argv) < 3:  # 需要三个参数
        print('Usage:python3 copy.py source.file target.file')
        sys.exit()
    
    #r'c:UsersAdministratorPycharmProjectspyhton18'
    #python copy.py C:source.file D:	arget.file
    #处理windows路径的方式
    with open(r'%s' % sys.argv[1],'rb') as read_f,
            open(r'%s' % sys.argv[2],'wb') as write_f:
        for line in read_f:
            write_f.write(line)

    文件其他操作

    #w文本模式的写,文件存在则清空,不存在则创建
    f=open('a.txt','w',encoding='utf-8')
    f.write('你好
    ')
    f.writelines(['1111
    ','222
    '])
    #a文本模式的追加,文件存在,光标跳到文件末尾,文件不存在则创建
    f=open(‘b.txt’,'a',encoding='utf-8')
    print(f.writable())  #True
    print(f.readable()) #Falese

    打开文件并不是应用程序自己的事情,打开文件后,我们拿到了变量名f,对应着一个值,这个f是应用程序拿着,操作系统还拿着打开的文件,如果要回收,应该是两个都要回收掉

    f=open('a.txt','wb')
    f.write('你好啊'.encode('utf-8'))

    print(f) # <_io.BufferedWriter name='a.txt'>
    f.close() # 向操作系统发起请求,关闭掉打开的文件,操作系统回收掉打开的文件,
    print(f) #<_io.BufferedWriter name='a.txt'>,虽然关掉了文件,但是f是应用程序级别定义的变量,这个变量是在这个变量f对应的值没有引用了才会被回收掉
    print(f.read) # 方法依然还有
    print(f.readable) # 方法依然还有
    f.read() # 不能运行,向操作系统发请求,操作系统已经关掉了这个文件,所以会报io出错

    #del f # 回收掉了应用程序级别的
    # a.txt 
    你好啊1
    你好啊2
    你好啊3
    
    f=open('a.txt','r',encoding='utf-8')
    print(f.read(3))    #文件打开方式为文本模式时,代表读取3个字符
    #你好啊
    # a.txt 
    你hello好啊1
    你好啊2
    你好啊3
    
    f=open('a.txt','r',encoding='utf-8')
    print(f.read(3))    #文件打开方式为文本模式时,代表读取3个字符
    #你he
    # a.txt 
    你hello好啊1
    你好啊2
    你好啊3
    
    f=open('a.txt','rb')
    print(f.read(3))    #文件打开方式为二进制模式时,代表读取3个字节
    
    #b'xe4xbdxao'

    print(f.read(3).decode('utf-8'))
    # 你      三个字节,unicode是三个字节存一个中文 
    print(f.read(2))  # b'xe4xbd'
    print(f.read(2).decode('utf-8'))  #报错  2个字节无法解出一个中文

    一.read(3):

        1.文件打开方式为文本模式时,代表读取3个字符        # 只有read的文本模式可以读字符,除此以外全是以字节为单位,不管文件打开模式是什么模式,都是以字节为单位

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

    #a.txt
    你好啊alex

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

    # 你好啊alex
    # 3
    # 好啊alex

    f=open('a.txt','r',encoding='utf-8')
    print(f.read(3))
    print(f.tell()) #以字节为单位显示
    print(f.read(1))
    f.seek(6)
    print(f.read(1))
    # 你好啊
    # 9
    # a
    # 啊

    二.其余文件内光标移动都是以字节为单位,如seek,tell,truncate

        1.seek有三种移动方式,0.1.2,其中1和2必须在b模式下进行,但无论哪种模式,都是以bytes为单位移动的

        f.seek(6,0)    f.seek(6,1)   f.seek(6,2)    # 0,1,2  指定的参照物不一样

        0  默认参照物为文件开头,

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

        2 从结尾位置为参照物

        f=open('a.txt','rb')        1和2必须在b模式下进行

        f.read(3)  read了三个字符,正好是三个中文字符,9个字节  f.seek(2,1)  当前光标是在第9个字节,在第9个字节往后seek了2个字节,所以光标现在在第11个字节

    f=open('a.txt','rb')
    print(f.read(3))   # 读了3个字节
    print(f.tell())   # 3
    f.seek(3,0)
    print(f.tell())  # 3
    print(f.read(1))  #读的是第4个字节

    f=open('a.txt','rb')
    print(f.read(3)) # b'xe4xbdxa0'
    print(f.tell()) # 3
    f.seek(3,1) # 基于当前光标往后移动了3个字节
    print(f.tell()) # 6


    # a.txt
    你好啊alex

    f=open('a.txt','rb')
    f.seek(0,2) #相对于文件末尾seek 0个位置
    print(f.tell()) # 13,文件的结尾
    f.seek(-1,2) #向左切一个字节
    print(f.read()) # b'x'

        2.truncate(没有用)是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为会直接清空文件,所以truncate要在r+或a或a+等模式下测试

    with open('a.txt','r+',encoding='utf-8') as f:
        f.truncate(9)  #  从文件开头开始截9个字节

    #你好啊

    模拟linux的tail 命令

    #python3 tail.py -f access.log
                0     1    2
    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.2)
       
    追加    # access.log
    with open('access.log','a') as f:
        f.write('1111
    ')

    函数

    问题:
         1.复杂度增大
         2.组织结构不清晰
         3.可读性差
         4.代码冗余
         5.可扩展性差

    如何解决问题:
         1.工具就是具备某一种功能的物件,就是程序中函数的概念
         2.事先准备工具的过程称为函数的定义
         3.遇到特定的场景拿来就用称为函数的调用

    分类:
         1.内置函数(解释器自带的)
         2.自定义函数
     
    1.先定义
          函数的定义与变量的定义类似,没有事先定义变量,而直接引用变量
          会报错,没有事先定义函数,而直接调用,就相当于在引用一个不存在的变量名

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

    2.再调用

    foo()  #先根据foo这个名字找到foo对应的值,然后这个值加上()运行

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

    def bar():
        print('from bar')
    
    def foo():
        print('from foo')
        bar()
    
    foo() 
    #定义阶段
    def foo():
        print('from foo')
        bar()
     
    def bar():
        print('from bar')
    
    #调用阶段
    foo()       # 不会报错

    # from foo
    # from bar

    函数定义语法

    def 函数名(arg1,arg2,arg3):
        '''注释'''
        函数体
        return  返回值
    
    函数名一般是动词

    定义的三种形式

    无参
        应用场景仅仅只是执行一些操作,比如与用户交互,打印
    有参
        需要根据外部代码传进来的参数,才能执行相应的逻辑

    def my_max(x,y):
        if x > y:
            print(x)
        else:
            print(y)
    
    my_max(1,2)
    # 2


    def my_max(x,y):
        if x > y:
            print(x)
        else:
            print(y)

    res=my_max(1,2)

    print(res)

    #2

    #None

    def foo():

        print('-----')

        return 123     # 函数内可以有多个return,但只能执行一次,整个函数就结束掉,并且会把return后的值作为函数执行的结果返回

        print('-----')

    foo()

    #-----

    空函数
        设计代码结构

    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)

            elif:

           .....
    main()

    文件补充: 

    #一行一行打印,同一时间,内存中只有一行内容
    with open('a.txt','r',encoding='utf-8') as f:
        for line in f:
        print(line)
    def func():
        print('from func')
        return [1,2,3],'a',1,{'a':3}
    res = func()
    print(res)
    
    return的返回值没有类型限制
        没有return,返回None,等同于return None
        return 一个值,返回该值
        return val1,val2,val3;返回(val1,val2,val3)

    什么时候该有返回值?

     调用函数,经过一系列的操作,最后要拿到一个明确的结果,则必须要有返回值
     通常有参函数需要有返回值,输入参数,经过计算,得到一个最终结果
     
    什么时候不需要有返回值?
     调用函数,仅仅只是执行一系列的操作,最后不需要得到什么结果
     则无需要有返回值

    函数调用的三种形式

    def my_max(x,y):
        if x > y:
            return x
        else:
            return y
      
    res = my_max(1,2)   #语句形式
    res1 = my_max(1,2)*10   #表达式形式
    res2 = my_max(my_max(1,2),3)  #函数调用可以当作另外一个函数的参数
    def func():
        print('from func')
        return [1,2,3],'a',1,{'a':3}
    
    res = func()
    print(res)

    函数参数:

    #在定义函数时,括号内的参数称为形参,不占内存空间
    def
    foo(x,y): #x,y是形参, x=1,y=2 形参就是变量名 print(x) print(y) #在调用函数时,括号内的参数称为实参,真正占内存空间的 foo(1,2) #1,2是实参 实参就是变量值

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

    参数的分类:

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

        1.位置形参:必选参数,多一个不行,少一个不行

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

    def foo(name,age):
        print(name)
        print(age)
    
    foo('tom',1)

    关键字参数

    def foo(name,age):
        print(name)
        print(age)
    
    foo(age=1,name='tom')

    默认形参

    x=100
    def foo(a,b=x):   #定义阶段
        print(a,b)
     
    x=0
    foo('egon')
    
    # egon 100
    
    默认参数只在定义阶段赋值一次,而且仅一次
    
    默认参数的值应该定义成不可变类型

    可变长参数:实参的个数不固定

    def foo(x,y,*args):
        print(x)
        print(y)
        print(args)
    
    foo(1,2,3,4,5,6,7)
    def foo(x,y,**kwargs):
        print(x)
        print(y)
        print(kwargs)
    foo(x=1,y=2,z=3,a=1,b=2)
    #装饰器的前身
    import
    time def register(name,age,sex='male'): print(name) print(age) print(sex) time.sleep(3)
    #统计register函数运行了多长时间,前提是不能更改register内部的源代码
    def wrapper(*args,**kwargs): start_time=time.time() register(*args, **kwargs) stop_time=time.time() print('run time is %s' %(stop_time-start_time))
    wrapper(
    'egon',age=18) #但是函数的调用方式变了,由调用register(),改为调用wrapper(),目前只能到这里,到装饰器时再把调用方式改为register()

     命名关键字参数:在*后面定义的形参称为命名关键字参数,

    必须是以关键字实参的形式传值

    def foo(name,age,*,sex):
        print(name)
        print(age)
        print(sex)
    
    foo('egon',18,sex='male')
    def foo(name,age,*,sex='male',group):
        print(name)
        print(age)
        print(sex)
        print(group)
     
    foo('egon',18,group='group1',sex='male')
    def foo(name,age,*args,sex='male',group):
        print(name)
        print(age)
        print(args)
        print(sex)
        print(group)
      
    foo('egon',18,19,20,300,group='group1') 

    # egon
    # 18
    # (19, 20, 300)
    # male
    # group1

    顺序很重要,但是没有全放在一起的场景

    def foo(name,age=18,*args,sex='male',group,**kwargs):
        pass

    函数对象

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

    1.被赋值

    def foo():
        print('from foo')
     
    f=foo
    print(f)    # 就是foo那个函数
    f()         # 相当于执行foo()

    2.可以当作参数传入

    def wrapper(func):
        print(func)     #打印函数foo的内存地址
        func()          #运行foo函数
     
    wrapper(foo)     # foo对应的内存地址传给func

    3.可以当作函数的返回值

    def wrapper(func):
        return func
    
    res=wrapper(foo)
    print(res)        #返回foo的内存地址

    4.可以当作容器类型的元素

    cmd_dic={
    'func':foo   #返回的是字典,{'func': <function foo at 0x00000250CA033E18>}
    }
    print(cmd_dic)
    
    cmd_dic['func']()  #运行foo函数
    def select(sql):
        '''select function'''
        print('select--->',sql)
    
    def insert(sql):
        '''insert function'''
        print('insert--->',sql)
    
    def update(sql):
        '''update function'''
        print('update--->',sql)
    
    def delete(sql):
        '''delete function'''
        print('delete--->',sql)
    
    cmd_dic = {
        'insert':insert,
        'update': update,
        'delete': delete,
        'select': select
    }
    
    def main():
        while True:
            sql=input('>>: ').strip()
            if not sql:continue
            cmd_info=sql.split()
            cmd=cmd_info[0]
    
            if cmd in cmd_dic:
                cmd_dic[cmd](cmd_info)
            else:
                print('cmd not exists')
    
    
    main()

    匿名函数lambda

    待补充

    内建函数

    待补充

    函数的递归调用

    待补充

    二分法

    待补充

    文件补充

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

    一次性把文件全部都到内存里,若文件很大,会撑爆内存

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

    同一时间,内存里只有一行内容

  • 相关阅读:
    easy-ui的data-options用法
    my_note
    定时器
    abp安装
    微信小程序
    几个免费的ui 后台
    abp创建实体的方法
    winform 开源项目
    func委托
    for update 锁行和锁表
  • 原文地址:https://www.cnblogs.com/Ryans-World/p/7218790.html
Copyright © 2020-2023  润新知