• Python 基础部分-4


    文件的基本操作

    open()

    用于文件处理

    操作文件时,一般需要经历如下步骤:

    • 打开文件
    • 操作文件
    • 关闭文件

    基本操作文件方式

    open(文件名/路径,模式,编码),默认模式为“只读”

    f = open('test.log', "r")
    data = f.read()
    f.close()
    print(data)
    
    >>>
    testlog

    打开文件时,需要指定文件路径和以何等方式打开文件,打开后,即可获取该文件句柄,日后通过此文件句柄对该文件操作。

    打开文件的模式: 

    • r ,只读模式【默认】
    f = open('test.log')
    data = f.read()
    f.close()
     print(data)
    
    >>>
    abc123
    • w,只写模式【不可读;文件不存在则创建;文件存在则清空内容;】
    f = open('test.log', 'w')
    data = f.write('defg123456') #以写方式覆盖文件
    f.close()
    print(data)
    
    >>>
    10  #写入10个字符
    f = open('test.log', 'w')
    data = f.read()
    f.close()
    print(data)
    
    >>>
    data = f.read()
    io.UnsupportedOperation: not readable#只写方式不能读取文件内同
    • x, 只写模式【不可读;文件不存在则创建;文件存在则报错】
    f = open('test2.log', 'x')#文件不存在,创建一个新的文件
    f.write("qwe456") 
    f.close()
    
    f = open('test2.log', 'x')
    f.write("zxcv123456") 
    f.close()
    
    >>>
        f = open('test2.log', 'x')
    FileExistsError: [Errno 17] File exists: 'test2.log'#文件已经存在,不能创建同名文件
    • a, 追加模式【不可读;文件不存在则创建;文件存在则只追加内容;】
    f = open('test2.log', 'a')
    data = f.write("9876543210")
    f.close()
    print(data)
    
    >>>
    10 #写入10个字符

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

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

        先读取文档,在文档末尾追加写入,指针移到最后

    f = open("test.log", 'r+', encoding = "utf-8")
    print(f.tell()) #显示指针位置,指针从开始向后读取
    f.write("123456")
    
    data = f.read()
    
    print(data)
    print(f.tell()) #读取文件后指针位置
    
    f.close()
    
    >>>
    0
    123456
    6
    • w+,写读【可读,可写】

        先把文件内容清空,从开始向后读取文件;重新写入内容后,指针移到最后,读取文件。

    f = open("test.log", 'w+', encoding = "utf-8")
    f.write("123456")#写入完成后,文档指针位置在文件末尾
    f.seek(0)#设定指针在文档开始
    data = f.read()
    print(data)
    • x+ ,写读【可读,可写】

        若文件存在,系统报错,建新文件,再写入内容后,指针移到最后,读取文件。

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

        文件打开同时,文档指针已经设定在最后, 写入文件后,指针留在文件的最后。

    f = open("test.log", 'a+', encodig"utf-8")
    f.write("987654")
    print(f.tell()) #显示指针位置
    f.seek(0)    #设定指针为文档最开始
    data = f.read()
    print(data) 
    
    >>>
    6 
    987654

    r+ w+ x+ a+都以指针位置读取或写入数据。

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

    • rb  或 r+b
    f = open('test2.log', 'wb')
    f.write(bytes("中国", encoding='utf-8'))
    f.close()
    
    
    f = open('test2.log', "rb")
    data = f.read()
    f.close()
    print(data)
    str_data = str(data, encoding='utf - 8')
    print(str_data)
    
    >>>
    b'xe4xb8xadxe5x9bxbd'
    中国
    • wb 或 w+b
    f = open('test2.log', 'wb')
    str_data = "中国"
    bytes_data = bytes(str_data, encoding = 'utf-8')#指定写如的编码
    f.write(bytes_data)
    f.close()
    f = open('test2.log', 'wb')
    f.write("中国")
    f.close()
    
    >>>
        f.write("中国")
    TypeError: a bytes-like object is required, not 'str'
    • xb 或 x+b
    • ab 或 a+b

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

    普通打开方式

    python内部将底层010101010的字节 转换成 字符串

    二进制打开方式

    python将读取将底层010101010的字节 再按照程序员设定的编码,转换成字符串。

    f = open('test2.log', 'wb')
    f.write(bytes("中国", encoding='utf-8'))
    f.close()
    
    f = open('test2.log', "rb")
    data = f.read()
    f.close()
    print(data)
    str_data = str(data, encoding='utf - 8')
    print(str_data)
    
    >>>
    b'xe4xb8xadxe5x9bxbd'
    中国

    文件操作内部函数

    f.flush()

    主动把内容刷新到硬盘内

    f = open("test.log", "r+", encoding="utf-8")
    f.write("123456789")#内容写入到内存中
    f.flush()#把内容刷新到硬盘内
    i = input(">>>") 

    f.readline()

    仅读取一行内容

    f1 = open("test.log", 'r+', encoding = 'utf-8')
    d = f1.realline()
    f.close()
    print(d)

    f.tell()

    显示指针位置

    f.seek()

    设定指针位置

    f.trucate()

    截取数据,仅保留指针前的数据

    f = open("test.log", "r+", encoding = "utf-8")
    print(f.tell())
    print(f.seek(6))
    
    f.truncate()
    f1.close()

    f.close()

    关闭文件,把文件保存在硬盘中

    使用for循环读取文件

    f = open("xxx", "r")
    for
    line in f: print(line)

    with 循环打开文件

    with open("xxx", 'r') as f:
        f.read()
    
    f = open("xxx", 'r') 
    f.read()
    #不需要f.close()关闭文件

    with支持同时打开两个文件,从源文件中逐行拷贝到目标文件中

    with open("test.log", 'r') as obj1, open ("test2.log", 'w') as obj2:
        for line in obj1:
            obj2.write(line)
    class file(object)
        def close(self): # real signature unknown; restored from __doc__
            关闭文件
            """
            close() -> None or (perhaps) an integer.  Close the file.
             
            Sets data attribute .closed to True.  A closed file cannot be used for
            further I/O operations.  close() may be called more than once without
            error.  Some kinds of file objects (for example, opened by popen())
            may return an exit status upon closing.
            """
     
        def fileno(self): # real signature unknown; restored from __doc__
            文件描述符  
             """
            fileno() -> integer "file descriptor".
             
            This is needed for lower-level file interfaces, such os.read().
            """
            return 0    
     
        def flush(self): # real signature unknown; restored from __doc__
            刷新文件内部缓冲区
            """ flush() -> None.  Flush the internal I/O buffer. """
            pass
     
     
        def isatty(self): # real signature unknown; restored from __doc__
            判断文件是否是同意tty设备
            """ isatty() -> true or false.  True if the file is connected to a tty device. """
            return False
     
     
        def next(self): # real signature unknown; restored from __doc__
            获取下一行数据,不存在,则报错
            """ x.next() -> the next value, or raise StopIteration """
            pass
     
        def read(self, size=None): # real signature unknown; restored from __doc__
            读取指定字节数据
            """
            read([size]) -> read at most size bytes, returned as a string.
             
            If the size argument is negative or omitted, read until EOF is reached.
            Notice that when in non-blocking mode, less data than what was requested
            may be returned, even if no size parameter was given.
            """
            pass
     
        def readinto(self): # real signature unknown; restored from __doc__
            读取到缓冲区,不要用,将被遗弃
            """ readinto() -> Undocumented.  Don't use this; it may go away. """
            pass
     
        def readline(self, size=None): # real signature unknown; restored from __doc__
            仅读取一行数据
            """
            readline([size]) -> next line from the file, as a string.
             
            Retain newline.  A non-negative size argument limits the maximum
            number of bytes to return (an incomplete line may be returned then).
            Return an empty string at EOF.
            """
            pass
     
        def readlines(self, size=None): # real signature unknown; restored from __doc__
            读取所有数据,并根据换行保存值列表
            """
            readlines([size]) -> list of strings, each a line from the file.
             
            Call readline() repeatedly and return a list of the lines so read.
            The optional size argument, if given, is an approximate bound on the
            total number of bytes in the lines returned.
            """
            return []
     
        def seek(self, offset, whence=None): # real signature unknown; restored from __doc__
            指定文件中指针位置
            """
            seek(offset[, whence]) -> None.  Move to new file position.
             
            Argument offset is a byte count.  Optional argument whence defaults to
    (offset from start of file, offset should be >= 0); other values are 1
            (move relative to current position, positive or negative), and 2 (move
            relative to end of file, usually negative, although many platforms allow
            seeking beyond the end of a file).  If the file is opened in text mode,
            only offsets returned by tell() are legal.  Use of other offsets causes
            undefined behavior.
            Note that not all file objects are seekable.
            """
            pass
     
        def tell(self): # real signature unknown; restored from __doc__
            获取当前指针位置
            """ tell() -> current file position, an integer (may be a long integer). """
            pass
     
        def truncate(self, size=None): # real signature unknown; restored from __doc__
            截断数据,仅保留指定之前数据
            """
            truncate([size]) -> None.  Truncate the file to at most size bytes.
             
            Size defaults to the current file position, as returned by tell().
            """
            pass
     
        def write(self, p_str): # real signature unknown; restored from __doc__
            写内容
            """
            write(str) -> None.  Write string str to file.
             
            Note that due to buffering, flush() or close() may be needed before
            the file on disk reflects the data written.
            """
            pass
     
        def writelines(self, sequence_of_strings): # real signature unknown; restored from __doc__
            将一个字符串列表写入文件
            """
            writelines(sequence_of_strings) -> None.  Write the strings to the file.
             
            Note that newlines are not added.  The sequence can be any iterable object
            producing strings. This is equivalent to calling write() for each string.
            """
            pass
     
        def xreadlines(self): # real signature unknown; restored from __doc__
            可用于逐行读取文件,非全部
            """
            xreadlines() -> returns self.
             
            For backward compatibility. File objects now include the performance
            optimizations previously implemented in the xreadlines module.
            """
            pass
    
    2.x
    Python 2.x
    class TextIOWrapper(_TextIOBase):
        """
        Character and line based layer over a BufferedIOBase object, buffer.
        
        encoding gives the name of the encoding that the stream will be
        decoded or encoded with. It defaults to locale.getpreferredencoding(False).
        
        errors determines the strictness of encoding and decoding (see
        help(codecs.Codec) or the documentation for codecs.register) and
        defaults to "strict".
        
        newline controls how line endings are handled. It can be None, '',
        '
    ', '
    ', and '
    '.  It works as follows:
        
        * On input, if newline is None, universal newlines mode is
          enabled. Lines in the input can end in '
    ', '
    ', or '
    ', and
          these are translated into '
    ' before being returned to the
          caller. If it is '', universal newline mode is enabled, but line
          endings are returned to the caller untranslated. If it has any of
          the other legal values, input lines are only terminated by the given
          string, and the line ending is returned to the caller untranslated.
        
        * On output, if newline is None, any '
    ' characters written are
          translated to the system default line separator, os.linesep. If
          newline is '' or '
    ', no translation takes place. If newline is any
          of the other legal values, any '
    ' characters written are translated
          to the given string.
        
        If line_buffering is True, a call to flush is implied when a call to
        write contains a newline character.
        """
        def close(self, *args, **kwargs): # real signature unknown
            关闭文件
            pass
    
        def fileno(self, *args, **kwargs): # real signature unknown
            文件描述符  
            pass
    
        def flush(self, *args, **kwargs): # real signature unknown
            刷新文件内部缓冲区
            pass
    
        def isatty(self, *args, **kwargs): # real signature unknown
            判断文件是否是同意tty设备
            pass
    
        def read(self, *args, **kwargs): # real signature unknown
            读取指定字节数据
            pass
    
        def readable(self, *args, **kwargs): # real signature unknown
            是否可读
            pass
    
        def readline(self, *args, **kwargs): # real signature unknown
            仅读取一行数据
            pass
    
        def seek(self, *args, **kwargs): # real signature unknown
            指定文件中指针位置
            pass
    
        def seekable(self, *args, **kwargs): # real signature unknown
            指针是否可操作
            pass
    
        def tell(self, *args, **kwargs): # real signature unknown
            获取指针位置
            pass
    
        def truncate(self, *args, **kwargs): # real signature unknown
            截断数据,仅保留指定之前数据
            pass
    
        def writable(self, *args, **kwargs): # real signature unknown
            是否可写
            pass
    
        def write(self, *args, **kwargs): # real signature unknown
            写内容
            pass
    
        def __getstate__(self, *args, **kwargs): # real signature unknown
            pass
    
        def __init__(self, *args, **kwargs): # real signature unknown
            pass
    
        @staticmethod # known case of __new__
        def __new__(*args, **kwargs): # real signature unknown
            """ Create and return a new object.  See help(type) for accurate signature. """
            pass
    
        def __next__(self, *args, **kwargs): # real signature unknown
            """ Implement next(self). """
            pass
    
        def __repr__(self, *args, **kwargs): # real signature unknown
            """ Return repr(self). """
            pass
    
        buffer = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
    
        closed = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
    
        encoding = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
    
        errors = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
    
        line_buffering = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
    
        name = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
    
        newlines = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
    
        _CHUNK_SIZE = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
    
        _finalizing = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
    
    3.x
    Python 3.x

    冒泡排序

    #利用新变量互换值
    a1 = 123
    a2 = 456
    
    temp = a1
    a1 = a2
    a2 = temp
    
    a1 = 456
    a2 = 123
    #实现列表元组互换
    li = [11,33,22,44,55]
    
    temp = li[1]
    li[1] = li[2]
    li[2]=temp
    
    print(li)
    
    >>>
    [11,22,33,44,55]
    #把列表里面的所有值进行比较
    li = [33,22,10,1]
    
    for i in range(len(li)-1): #循环列表次数
        # i = 0              1   2   3
        #current:      li[0] 1   2   3
        #next_value:   li[1] 2   3   4 #列表li里面没有li[4],因此需要减少一次循环次数
        current = li[i]
        next_value = li[i+1]
        print(i, current, next_value)
    
    >>>
    0 33 2 #第一次循环
    1 2 10 #第二次循环
    2 10 1 #第三次循环
    #循环一次列表,仅把一个最大的元素排在最右方
    li = [33,2,10,1] for i in range(len(li)-1): #循环列表元素 if li[i] > li[i+1]: #元素互换的条件 temp = li[i] li[i] = li[i+1] li[i + 1] = temp print(li) >>> [2, 10, 1, 33]
    li = [33,2,10,1]
    
    for i in range(len(li)-1): #元素内部从左往右循环比较三次,等于列表长度减1那么多次,如列表4个元素,两两比较,需要比较三次1-(33, 2), 2-(2,10), 3-(10, 1)
    
        if li[i] > li[i+1]:
            temp = li[i]
            li[i] = li[i+1]
            li[i + 1] = temp
    
    print(li)
    
    >>>
    [2,10,1,33]
        
    li = [33,2,10,1]
    for j in range(1, len(li)): #由于i循环每完成一次,下一次i循环排序的元素就减少一次, j的数值应为1,2,3 到数列的长度为止。
        #j: 1 ,2 ,3, i循环中两两比较的次数
        for i in range(len(li)-j): #元素内部循环比较完成一次,得到最右边的一个最大元素,下一次循环比较的元素就减少一个,j代表每次完成循环减少的排序的元素。
            if li[i] > li[i+1]:
                temp = li[i]
                li[i] = li[i+1]
                li[i + 1] = temp
    
    print(li)
    
    >>>
    [1, 2, 10, 33]

    递归

    递归指的是这样一个数列:1、1、2、3、5、8、13、21、……

    递归满足2个条件:

    1)有反复执行的过程(调用自身)

    2)有跳出反复执行过程的条件(递归出口)

    递归执行过程中参数传递过程

    def f1():
        return "f1" #8. 执行f1(),返回"f1", f1返回给函数调用者f1()="f1"=>f2()=>f3()=>f4(),最后有ret接受返回值“f1”
    
    def f2():
        r = f1() #6. 执行f2(),得到 r = f1()
        return r #7. r = f1(), 返回r,即返回执行f1()
    
    def f3(): 
        r = f2() #4. 执行f3(),得到 r = f2()
        return r #5. r = f2(), 返回r,即返回执行f2()
    
    def f4():     
       r = f3() #2.执行f4(),得到 r = f3() return r #3.r = f3(), 返回r,即返回执行f3() ret = f4() # 1.解释器读取函数,把f1,f2,f3,f4的函数存入内存,执行函数f4(), ret接受f4返回值r
    print(ret)
    def f4(a1, a2):
        print(a1, a2)
    
        #a1 = 0, a2 = 1,a3 = 1
        #a1 = 1, a2 = 1, a3 = 2
        #a1 = 1, a2 = 2, a3 = 3
    
        a3 = a1 + a2 #
        f4(a2, a3) #嵌套上面的参数循环执行函数
    
    f4(0, 1)
    
    >>> 
    0 1
    1 1
    1 2
    2 3
    3 5
    5 8
    8 13
    13 21
    21 34
    34 55
    55 89
    ...

     练习:利用递归获取斐波那契数列中的第 10 个数,并将该值返回给调用者。

    def f5(depth, a1, a2): #depth数列的第n个数
      if depth == 10: return a1 #数列第十个数的返回值,最终有启始的函数'ret'接受 a3 = a1 + a2 r = f5(depth +1, a2, a3) return r ret = f5(1,0,1)#数值0为第一个斐波那契的数值 print(ret) >>> 34

     装饰器

    装饰器用于装饰某个函数或者方法或者类,在调用者调用方式不变的情况下,可以在函数执行前或执行后做其他操作。

    装饰器本质,将 原函数 封装到 新的函数里面(),使执行新函数时,既可以实现新函数的功能,有可以执行就函数的功能。

    def outer(func):#参数func = 以原来的f1函数作为参数
        def inner():#inner函数作为新的f1函数执行
            print("hello")
            r = func()#由于outer(func)的参数为f1,此处执行原来的f1函数
            print("end")
            return r
        return inner #@outer inner = f1
                                                                                
    @outer #f1 = outer(f1)  1.执行outer函数,并且将其下面的函数名f1当做参数,func = f1;
                  2.将outer的返回值inner重新赋值给f1,f1=(outer的返回值)=inner, 执行f1() = 执行inner()
    def f1(): print("F1")
      return ooo
    def f2(): print("F2") def f3(): print("F3") """ . . . """ def f100(): print("F100")
       f1()
    >>> hello F1 end
    ooo

     只要函数应用装饰器,那么函数就被重新定义为:装饰器的内层函数。

    装饰器装饰含两个参数的函数

    def outer(func):
        def inner(a1, a2):
            print("123")
            ret = func(a1, a2)
            print("456")
            return ret
        return inner
    
    @outer  #inner = index(a1, a2),index函数被装饰到inner函数里面,
            #执行index函数是需要两个参数,因此装饰器函数也需要两个参数inner(a1,a2)。
            #装饰器内部执行func() = 执行index(),因此也需要在func函数中加入两个参数。func(a1, a2)
    def index(a1, a2):
        print("执行函数")
        return a1 + a2
    
    ret = index(1, 2)
    print(ret)

    装饰器装饰含N个参数的函数

    def f1(*args,**kwargs):#多参数函数
        print(args)
        print(kwargs)
    
    f1(11, 22, 33, 44, 55, 66, 77, 88, k1=123, k2=321)

    >>>

      (11, 22, 33, 44, 55, 66, 77, 88)
      {'k2': 321, 'k1': 123}

    def outer(func):
        def inner(*args, **kwargs):#
            print(args)
            ret = func(*args, **kwargs)#
            print(kwargs)
            return ret
        return inner
    
    
    @outer
    def index(a1, a2, k1=123, k2=456):
        print("执行函数")
        return a1 + a2
    
    ret = index(10, 20, k1=123, k2=456)
    print(ret)
    
    >>>
    (10, 20)
    执行函数
    {'k1': 123, 'k2': 456}
    30

    多个装饰器装饰同一个函数 

    def outer_0(func):
        def inner(*args, **kwargs):
            print("python 3.5")
            ret = func(*args, **kwargs)
            return ret
        return inner
    
    def outer(func):
        def inner(*args, **kwargs):
            print(args)
            ret = func(*args, **kwargs)
            print(kwargs)
            return ret
        return inner
    
    @outer_0
    @outer
    def index(a1, a2, k1=123, k2=456):
        print("执行函数")
        return a1 + a2
    
    >>>
    python 3.5
    (10, 20)
    执行函数
    {'k1': 123, 'k2': 456}
    30

    多装饰器嵌套原理

    # @outer:  inner = index, outer(func) = outer(index)
    # inner = 新的 index 函数 
    # index(*args, **kwargs):
    #   print(args)
    #   ret = index(*args, **kwargs)
    #       print("执行函数")
    #       return a1 + a2
    #   print(kwargs)
    #   return ret
    
    #@outer0:inner = 新的 index 函数 + 新的 inner, outer0(func) = outer0(inner(index))
    #inner =out0 + index(*args, **kwargs) 函数 +
    #index(*args, **kwargs):
    #   print("python 3.5")
    #   print(args)
    #   print("执行函数")
    #   return a1 + a2
    #   print(kwargs)
    #   return ret

    装饰器总结 @ 

    把index函数作为outer的参数去执行outer函数

    index的整体放入内存 当内层函数inner中对index进行调用它作为一个新的函数

    @outer

    1. 执行outer函数,将index作为参数传递

    2. 将outer的返回值,重新赋值给index

  • 相关阅读:
    Java 练习(获取两个字符串中最大相同子串)
    STM32F103 实现 简易闹钟小程序
    STM32F103 实现 LCD显示年月日时分秒星期 并可逐值修改的日期 小程序
    Docker报错之“Failed to get D-Bus connection: Operation not permitted”
    数据结构解析
    每天一条DB2命令-004
    每天一条DB2命令-003
    每天一条DB2命令-002
    ElasticSearch系列
    模块三 GO语言实战与应用-BYTES包与字节串操作(下)
  • 原文地址:https://www.cnblogs.com/Sam-r/p/5534660.html
Copyright © 2020-2023  润新知