python文件的操作

open() 可以创建类IO的实例化对象

class IO(Generic[AnyStr]):
Generic base class for TextIO and BinaryIO,This is an abstract, generic version of the return of open().

class TextIO(IO[str]):Typed version of the return of open() in text mode.

class BinaryIO(IO[bytes]):Typed version of the return of open() in binary mode

这里写图片描述

f = open('student_msg', encoding='utf-8', mode='a+')  # 打开一个文件,赋值给f

print(type(f), f) # f文件句柄是属于一个类叫<class '_io.TextIOWrapper'>,属于可迭代对象。(io ---> input and out)

print(dir(f))   # 打印这个类的所有属性和方法
>>>
['_CHUNK_SIZE', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable', '_finalizing', 'buffer', 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'line_buffering', 'mode', 'name', 'newlines', 'read', 'readable', 'readline', 'readlines', 'reconfigure', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 'write_through', 'writelines']


print(f.__dict__)  # f 这个实例化对象中的属性 {'mode': 'a+'}

源码对其的解释定义
'''
========= ===============================================================
    Character Meaning
    --------- ---------------------------------------------------------------
    'r'       open for reading (default)  默认只读
    'w'       open for writing, truncating the file first  首先把文件截断(全删了)
    'x'       create a new file and open it for writing
    'a'       open for writing, appending to the end of the file if it exists  追加模式
    'b'       binary mode  二进制模式,打开图片或者非文本格式时
    't'       text mode (default)  默认读取文本
    '+'       open a disk file for updating (reading and writing)  可读可写
    ========= ===============================================================
'''

几种常用的方法

  1. readline() 和 .readlines()
    查找文件中的内容用什么模式。试试用六种方式执行的结果。
    在register文件中有以下内容,分别执行这六种方式返回的结果:
    ‘’’
    这些是文件中的内容
    dumingjun
    mickle|male
    ‘’’
  • mode=‘r’ 只读模式
with open('register', encoding='utf-8', mode='r') as f:
    print(f.readline())
    print(f.readlines())

运行结果



这些是文件中的内容

['dumingjun\n', 'mickle|male']


  • mode=‘r+’
with open('register', encoding='utf-8', mode='r+') as f:
    print(f.readline())   # 先读一行
    print(f.readlines())   #然后往下执行,把每行作为一个字符串放入列表这个容器中,换行符为\n

运行结果


这些是文件中的内容     

['dumingjun\n', 'mickle|male']  

  • mode=‘w’
with open('register', encoding='utf-8', mode='w') as f:
    print(f.readline())
    print(f.readlines())

运行结果

Traceback (most recent call last):
    print(f.readline())
io.UnsupportedOperation: not readable   # 报错原因:’w‘模式是无法读的
  • mode=‘w+’
with open('register', encoding='utf-8', mode='w+') as f:
    print(f.readline())
    print(f.readlines())

运行结果:(文件内容已经为空)

        # 先清空,然后接下来执行了f.readline() 由于为空,所以返回了空的字符
[]    # 接下来执行f.readlines(), 返回一个空列表

  • mode=‘a’
with open('register', encoding='utf-8', mode='a') as f:
    print(f.readline())
    print(f.readlines())

运行结果:(文件内容不变)

Traceback (most recent call last):
    print(f.readline())
io.UnsupportedOperation: not readable  # 报错原因,’a‘模式只能add,增加,不可读,因为’a'模式进去时光标自动放在文件的末尾。
'''

  • mode=‘a+’
with open('register', encoding='utf-8', mode='a+') as f:
    print(f.readline())
    print(f.readlines())

运行结果:(文件内容不变)

   # 因为光标是放在最后,所以读取的内容为空
[]     # 同理redlines()返回的是一个空列表。

这里写图片描述
这里写图片描述
这里写图片描述
总结: 阅读,查找相关内容,只能用‘r’或 ‘r+’模式
这里写图片描述
二 . 新建一个文件,并且添加内容,用什么模式呢?
要求
创建名为’msg’的文件,并写入内容以下内容:
’Duminjun is swimming\n今晚吃鸡‘

  • r+模式
with open('msg9', encoding='utf-8', mode='r+') as f:
     f.write('Duminjun is swimming\n今晚吃鸡')

运行结果:

Traceback (most recent call last):
    with open('msg', encoding='utf-8', mode='r+') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'msg'  # 没有名为‘msg’的文件,证明r+模式不可添加文件

  • a 模式
 with open('msg', encoding='utf-8', mode='a') as f:
     f.write('Duminjun is swimming\n今晚吃鸡')

运行结果(已经在本目录添加了‘msg’的文件,打开文件显示了以下内容:

Duminjun is swimming   # a 模式可以创建文件并写入
今晚吃鸡

  • a+模式
with open('msg', encoding='utf-8', mode='a+') as f:
     f.write('Duminjun is swimming\n今晚吃鸡')

运行结果:和以上a运行结果一样

  • w模式
with open('msg', encoding='utf-8', mode='w') as f:
    f.write('Duminjun is swimming\n今晚吃鸡')

结果:和a模式一样

  • w+ 模式
with open('msg4', encoding='utf-8', mode='w+') as f:
     f.write('Duminjun is swimming\n今晚吃鸡')

运行结果:和a模式行的结果一样
三 - 如果有名为’msg‘的文件里面有’Duminjun is swimming\n今晚吃鸡‘这些内容,现在要增加以下内容
’\nLaura is a playing tennis,What are you dong?’

  • r
with open('msg', encoding='utf-8', mode='r') as f:
    f.write('\nLaura is a playing tennis,What are you dong?')

运行结果

Traceback (most recent call last):
    f.write('\nLaura is a playing tennis,What are you dong?')
io.UnsupportedOperation: not writable          # f这个实例化对象中没有可读这一属性
  • r +
with open('msg', encoding='utf-8', mode='r+') as f:
     f.write('\nLaura is a playing tennis,What are you dong?')

运行结果:(没有报错,文件内容如下:)

Laura is a playing tennis,What are you dong?s swimming
今晚吃鸡            # 添加的内容已经插入到了最前面,r+模式可以写入文件,但是进入文件句柄时光标在最前面

如果想要r+模式增加内容到文末,可以先读完全部内容,光标就到了最后,然后在把内容写入文件

with open('msg', encoding='utf-8', mode='r+') as f:
     f.readlines()   
     f.write('\nLaura is a playing tennis,What are you dong?')  

运行结果(文件内容如下)

Duminjun is swimming
今晚吃鸡
Laura is a playing tennis,What are you dong?
  • w
 with open('msg', encoding='utf-8', mode='w') as f:
     f.write('\nLaura is a playing tennis,What are you dong?') 
  • 运行结果,文件中显示以下内容:
Laura is a playing tennis,What are you dong?  # 原文件内容全部清空,写入了新增加的内容
  • w+
 with open('msg', encoding='utf-8', mode='w+') as f:
     f.write('\nLaura is a playing tennis,What are you dong?')

运行结果:和w运行结果一样

  • a
 with open('msg', encoding='utf-8', mode='a') as f:
     f.write('\nLaura is a playing tennis,What are you dong?')

运行结果,文件内容如下

Duminjun is swimming
今晚吃鸡
Laura is a playing tennis,What are you dong?   # 已经成功到文末
  • a+
with open('msg', encoding='utf-8', mode='a+') as f:
     f.write('\nLaura is a playing tennis,What are you dong?')

运行结果:和a模式结果一样

这里写图片描述
这里写图片描述

四,例题:写函数,用户传入修改的文件名,与要修改的内容,执行函数,完成整个文件的批量修改操作

def modify_update():
    file_name = input('please input the file name: ').strip()
    modify_content = input('please input the content to modified: ')
    new_content = input('please input new content you want to replace: ')
    with open('{}'.format(file_name), encoding='utf-8', mode='r+') as f, \
        open('msk5', encoding='utf-8', mode='w+') as f1:            # 打开两个文件句柄,一个读原文档,一个写入修改后的内容
        for i in f:
           f1.write(i.replace('{}'.format(modify_content), '{}'.format(new_content)))
#  边循环原文件每一行,边添加新的一行到另外一个文件,如果replace没有找到旧词,字符串不会做任何修改,所以不用if...else语句
'''
w,w+在一个句柄里操作不会每次都清空,只有重新以w,w+模式打开一个句柄并且使用f.write()才会清空,就是说两个句柄是没有关系的完全分开的,就好比两个变量或者两个实例化对象时完全不相关的。由于replace()返回的是一个新的字符串,所以原来的文件是不变的,只有循环添加修改后的内容到新的文件。
'''

五,文件句柄,文件句柄类型,f.readline(), f.readlines(), for line in f 的区别

假设'user'文件中有如下内容:
# import time()
# class Student:
#     def __init__(self, name):
#         self.name = name
#
#     def select_course(self):
#         print('Succussful Choose Class')
#         with open('log', 'a', encoding='utf-8') as f:
#             f.writer('%s : %s



with open('userinfo') as f:
    for i in f:
        print(i, type(i))  
    print(f, type(f))
    print(f.readlines)  # 类io的作用是把这个方法的内部代码块的地址放到一个wrapper文本容器中等待调用,加个括号可执行。 <built-in method readlines of _io.TextIOWrapper object at 0x000001C2D7F3AB40>
    print(f.readline)  # <built-in method readline of _io.TextIOWrapper object at 0x000001C2D7F3AB40>
    print(f.readline(), type(f.readline()))   # <class 'str'>  # 空字符串,因为被for循环取完了值
    print(f.readlines(), type(f.readlines))  # [] <class 'builtin_function_or_method'>
    a = f.readline()
    print(a, type(a))  #  <class 'str'>
    
执行结果如下
>>>

# import time()
 <class 'str'>
# class Student:
 <class 'str'>
#     def __init__(self, name):
 <class 'str'>
#         self.name = name
 <class 'str'>
#
 <class 'str'>
#     def select_course(self):
 <class 'str'>
#         print('Succussful Choose Class')
 <class 'str'>
#         with open('log', 'a', encoding='utf-8') as f:
 <class 'str'>
#             f.writer('%s : %s <class 'str'>
<_io.TextIOWrapper name='userinfo' mode='r' encoding='cp936'> <class '_io.TextIOWrapper'>
<built-in method readlines of _io.TextIOWrapper object at 0x000001C2D7F3AB40>
<built-in method readline of _io.TextIOWrapper object at 0x000001C2D7F3AB40>
 <class 'str'>
[] <class 'builtin_function_or_method'>
 <class 'str'>

例5总结:f属于’_io.TextIOWrapper’类的一个实例化对象,是个迭代器(类的方法中有__iter__和__next__方法),

  • 可用遍历句柄用for循环取值,
  • 可用readline()类的方法取值,返回的是字符串格式。
  • 可用readlines()的类的方法取值,返回是列表。
  • 这三个方法和next一样,取一个迭代器就少一个值,取完就没有了,句柄中的指针到了最后,指针只会向前,不会往回看,所以永远取不到前面的值了,后面如果没有就返回一个空字符串。
  • 如果想再对取过值的句柄进行操作,必须重新打开一个文件句柄。
    plus
    python中with上下文管理
class A:
    def __enter__(self):
        print('进入代码')

    def __exit__(self, exc_type, exe_val, exc_tb):
        print('代码结束')


a = A()


with a:  
    print('代码执行')
    
 # 上下文管理的关键字,with a这个A的实例化对象后,自动调用了a中的__enter__方法,当代码块执行完后最后调用a中的__exit__方法。类似with open(file),首先调用所属的类_io.TextIOWrapper的__enter__方法打开文件,再执行代码块,最后调用__exit__方法关闭文件。

执行结果

进入代码
代码执行
代码结束
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值