• python学习之路(六)


    今天来介绍一下文件的操作,包括文件的增删改查,以及字符编码与转码,还有一些简单的函数操作。

    要对文件进行操作,首先要打开一个文件,而打开文件需要声明要对这个文件干什么,比如读('r'),写('w'),追加('a'),读写('r+'),写读('w+'),还需要告诉系统,用什么字符集来打开,如utf-8或者Unicode等
    首先介绍一下文件的读取。  f.read 这个是读取整个文件的内容。

    首先有个叫'yesterday'的文本文件(就当他有,我这里没写这个文件)
    f=open('yesterday','r',encoding='utf-8')
    data1=f.read
    data2=f.read
    print(data1,“1”)
    print(data2,“2”)
    f.close

    你会发现,输出的结果是data1输出的是文件的内容,data2输出的是空,而不是输出了两次整个文件,也不是读了两行。因为在这里,要介绍一个句柄的东西,大家可以理解成光标,f.read在读完文件的时候,句柄就停留在文件最后的位置,

    在执行data2的时候,句柄在最后的位置,再往后面是没有内容的,所以输出的是一个空。而不是读第二遍文件。

    这里还要注意一点的是,文件无论进行什么 操作,只要打开了文件,后面一定要关闭,f.close。

    有时候我们可能不需要直接读取整个文件,这里介绍一下按行读取  f.readline

    这里介绍几种方法
    f=open('yesterday','r',encoding='utf-8')
    我们可以从第一行读几行
    for i in range (5):
      print(f.readline())
    也可以读完整个文件
    for line in f.readlines():
    print(line.strip())

    这里还有一种操作是按行输出,并写出这是第几行 用的是enumerate
    for index,line in enumerate(f.readlines()):
      print(index,line)

    不过,readline命令是全读到内存里,运行速度不如在内存中读一行,删一行的速度快
    for line in f :
      print(line)

    文件的读取介绍的差不多了,下面介绍文件的写入,‘w’模式是写入模式,他是创建(如果文件存在就覆盖)一个文件。

    f=open('yesterday','w',encoding='utf-8')
    f.write("abc")
    f.weite("456")
    f.close

    代码执行之后会看到yesterday文件中有一行数据  abc456 ,他没有向我们程序中那样,写成两行,也是因为上文中提到的句柄,因为在写完abc之后,句柄就停留在了abc的后面,没有自动换行,所以在写入456的时候,他会紧接着abc写。

    这里还有一点,就是在文件的写入过程中,不是write代码执行完成后,就立即写入硬盘文件中,而是在关闭这个文件的时候,数据才会一起写入磁盘中,之前都是保存在内存中的,所以这里也必须记得关闭文件。

    如果想执行完write 就立即写入的话,可以再write语句后面使用 f.flush()  这个是直接写入到文件中,不需要关闭文件,括号中如果填数字,代表写这么多字符后自动写入文件。

    还有几种文件的打开模式

    A.  “a” 在这个模式下,写入的数据都会追加在原文件的末尾,而不会覆盖原文件。

    B.  “r+”这个是读写模式,所谓读写模式是先读再写的模式。当你读取了三行后再写入,新写入的文件会出现在第三行的末尾而不是第四行。因为读取结束时,文件的句柄停留在了第三行的结尾,而且这个句柄不会自动移动到第四行,所以新写的数据会出现在第三行结束。读写模式,可读可写可追加,平时用处比较多。

    C.  “w+”这个是写读模式,在这个模式下,系统会自动去寻找有没有这个文件,如果没有的话直接新建一个文件,如果有的话,覆盖这个文件。在读写模式下,先读取文件是没有用的,因为文件被覆盖,读不到任何数据。在写入的时候,虽然可以移动句柄,但是无法在移动后的句柄处写入,还是会写入在文件的末尾处。

    D. "a+"是追加读写 

    E.  "rb"让文件以二进制方式读取出来。

    F.  “wb”以二进制方式写入。这时候就不能输入英文,汉字等了,写入的时候会报错,因为输入的不是二进制。

    这里在介绍一下文件的修改。文件的修改有两种方式。

    1.把文件全读取到内存中,修改完成后再全部写入。这种方法不推荐用,因为当文件过大时,内存可能无法处理这个文件,而且就算是一般的文件,处理速度也会比较慢,因为占用内存比较大。

    2.打开原文件的同时打开另一个文件,将修改完成的文件写入另一个新的文件,这样可以一部分一部分的去执行,提高运行速度,节省内存,是主流的修改文件的方法。

    修改的语句可以用replace

    for line in f :
        if "abc" in line :
            line = line.repiace("abc","def")
    这就实现了一个,将文件中的abc替换成def的功能。

    打开文件还有另一种操作,就是用with,用with的好处就是不用去关闭文件,他会自动帮你处理好

    with open ("yesterday","r",encoding="utf-8") as f :
        print (f.readline())
    
    打开多个文件的方法是
    with open ("yesterday1","r",encoding="utf-8") as f ,
        with open ("yesterday2","r",encoding="utf-8") as ff :
    下一个文件要记缩进。

    下面介绍字符编码和转码 
    python3中默认的编码是Unicode。在py3中encode,在转码的同时还会把string 变成bytes类型,decode在解码的同时还会把bytes变回string。

    不管是encode还是decode。只要记住在不同的字符集转换的时候,都要经过Unicode再转到别的字符集!!!

    utf-8是Unicode的扩展集,所以Unicode可以在utf-8下直接打印出来。

    最后介绍一部分函数。

    所以,先定义一个函数

    def test (x) :
       x+=1
       return 0

    这样,我们就定义了一个名为test的函数,他的形参是x,他的函数体是x+=1, 返回值是一个0。如果未在函数中指定return,那这个函数的返回值为None
    函数和过程最大的区别是函数必须有返回值,而过程是没有返回值的。

    return 后面可以跟任何东西,他代表函数执行完成的一个标志,返回这个值就相当于说函数已经执行完成,而在函数中,return后面的语句也不会被执行,因为return是这个函数的结尾。

    假设一个 a= test(1) 打印他会得到0.这就是上个函数执行完成的标志 。也可以return x 。这个会打印出一个2.因为函数中有x+=1.执行完成后x就变成了2.

    形参和实参:

    形参:变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量

    实参:可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值

    就像刚才上边的例子 x 就是一个形参。而a=test(1)中的1就是实参。

    一个函数可以有多个形参和实参,比如下面代码

    def test(x,y):
        print (x)
        print (y)
        return 0
    
    test(1,2)
    test(x=1,y=2)
    test(1,y=2)
    以上三种调用函数的传参方法都对,前两种不必多说,第三种方法,在函数中,他会主动识别位置参数,然后在去看赋值。但是不能将赋值卸载位置参数前面,会报错

    函数还能赋默认参数

    def test(x,y=1)
        print(x)
        print(y)
        return 0
    
    test(1)
    test(1,3)
    test(1,y=3)
    test(x=1)
    test(x=1,y=3)
    以上方法都正确,默认参数是可以赋也可以不赋值的。这种多用于有默认选项的情况,如默认国籍,或者默认数据库服务器端口等

    函数也可以通过元祖,字典等方式传值

    def test (*args)
         print(args)
         return 0
    
    test(1,2,3,4)
    test(*[1,2,3,4])
    这两种也都可以的
    
    这种传值方法多用于与传单一参数一起传递值得情况,比如一开始我定义了一个函数,只有一个形参x ,但是后来发现形参不够,还想加,就可以用下面的方法,省的日后再去改代码
    def test (x,*args)
        print (x)
         print (args)
         return 0
    
    这时候可以用test(1,2,3,4)传值
    输出的结果为 
    12,3,4)

    通过字典传值

    def stu_register(name,age,*args,**kwargs): # *kwargs 会把多传入的参数变成一个dict形式 
        print(name,age,args,kwargs) 
      return 0 stu_register(
    "Alex",22) #输出 #Alex 22 () {}#后面这个{}就是kwargs,只是因为没传值,所以为空 stu_register("Jack",32,"CN","Python",sex="Male",province="ShanDong") #输出 # Jack 32 ('CN', 'Python') {'province': 'ShanDong', 'sex': 'Male'}

    既然降到了函数,那么必然少不了局部变量和全局变量

    在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
    全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
    当全局变量与局部变量同名时:
    在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用
     
    x=1
    def aaa(x,y)
        print(x)
        x=3
        print(x)
        c=x+y    
        return 0
    aaa(x,1)
    print(x)
    这个函数执行完之后是
    1
    3
    1
    在程序最顶端的是全局变量
    而在函数里面的x是局部变量
    虽然在函数里面可以通过语句global改变全局变量,但是不建议使用。
    而且,只有str ,int 不能再函数中改变局部变量。
    但是,列表,元祖,字典,集合,类,都可以在局部变量中改变全局变量。
     
    递归函数

    在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

    def calc(n): 
        print(n) 
        if int(n/2) ==0: 
            return n 
        return calc(int(n/2)) 
      
    calc(10) 
      
    输出: 
    10
    5
    2
    1 

    递归特性:

    1. 必须有一个明确的结束条件

    2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少

    3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

    高阶函数

    变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

    注:abs是取绝对值

    def add(x,y,f): 
        return f(x) + f(y) 
      
      
    res = add(3,-6,abs) 
    print(res) 
     
  • 相关阅读:
    青山一别
    Spring Mvc Long类型精度丢失
    Spring 版MediatR--中介者模式实现库
    Spring 实现策略模式--自定义注解方式解耦if...else
    spring泛型注入
    Spring Boot Mvc 统一返回结果
    简化mapstruct代码: mapstruct-spring-plus
    .NET后端开发编码规范
    深度优先遍历(DFS)和广度优先遍历(BFS)的实现与简单应用
    将HTML字符串编译为虚拟DOM对象的基础实现
  • 原文地址:https://www.cnblogs.com/lovelyming/p/6936389.html
Copyright © 2020-2023  润新知