设为首页 收藏本站
查看: 668|回复: 0

[经验分享] 第十二章 Python文件操作

[复制链接]

尚未签到

发表于 2018-8-4 10:02:45 | 显示全部楼层 |阅读模式
  12.1 open()
  open()函数作用是打开文件,返回一个文件对象。
  用法格式:open(name[, mode[, buffering[,encoding]]]) -> file object
  name 文件名
  mode 模式,比如以只读方式打开
  buffering 缓冲区
  encoding 返回数据采用的什么编码,一般utf8或gbk
  Mode
  Description
r只读,默认w只写,打开前清空文件内容a追加a+读写,写到文件末尾w+可读写,清空文件内容r+可读写,能写到文件任何位置rb二进制模式读wb二进制模式写,清空文件内容  例如:打开一个文件
>>> f = open('test.txt', 'r')  
>>> f.
  
f.__class__(         f.__new__(           f.encoding           f.readinto(
  
f.__delattr__(       f.__reduce__(        f.errors             f.readline(
  
f.__doc__            f.__reduce_ex__(     f.fileno(            f.readlines(
  
f.__enter__(         f.__repr__(          f.flush(             f.seek(
  
f.__exit__(          f.__setattr__(       f.isatty(            f.softspace
  
f.__format__(        f.__sizeof__(        f.mode               f.tell(
  
f.__getattribute__(  f.__str__(           f.name               f.truncate(
  
f.__hash__(          f.__subclasshook__(  f.newlines           f.write(
  
f.__init__(          f.close(             f.next(              f.writelines(
  
f.__iter__(          f.closed             f.read(              f.xreadlines(
  open()函数打开文件返回一个文件对象,并赋予遍历f,f就拥有了这个文件对象的操作方法。
  方法
  描述
f.read([size])读取size字节,当未指定或给负值时,读取剩余所有的字节,作为字符串返回f.readline([size])从文件中读取下一行,作为字符串返回。如果指定size则返回size字节f.readlines([size])读取size字节,当未指定或给负值时,读取剩余所有的字节,作为列表返回f.write(str)写字符串到文件f.writelines(seq)写序列到文件,seq必须是一个可迭代对象,而且要是一个字符串序列f.seek(offset[, whence=0])在文件中移动文件指针,从whence(0代表文件起始位置,默认。1代表当前位置。2代表文件末尾)偏移offset个字节f.tell()返回当前在文件中的位置f.close()关闭文件f.flush刷新缓冲区到磁盘  12.2 文件对象操作
  写一个测试文件test.txt举例:
# cat test.txt  
1.Python
  
2.Java
  
3.C++
  
4.Ruby
  12.2.1 read()读取所有内容
>>> f = open('test.txt', 'r')  
>>> f.read()
  
'1.Python\n2.Java\n3.C++\n4.Ruby\n'
  指定读取多少字节:
>>> f = open('test.txt', 'r')  
>>> f.read(9)  # 获取指定字节
  
'1.Python\n'
  12.2.2 readline()读取下一行内容
>>> f = open('test.txt', 'r')  
>>> f.readline()
  
'1.Python\n'
  
>>> f.readline()
  
'2.Java\n'
  12.2.3 readlines()读取所有内容返回一个列表
>>> f = open('test.txt', 'r')  
>>> f.readlines()
  
['1.Python\n', '2.Java\n', '3.C++\n', '4.Ruby\n']
  12.2.4 wirte()写入字符串到文件
>>> f = open('test.txt', 'a')  # 以追加方式打开文件  
>>> f.write("5.Shell\n")  # 这一步并没有真正写到文件
  
>>> f.flush()  # 刷新到磁盘才写到文件
  
# cat test.txt
  
1.Python
  
2.Java
  
3.C++
  
4.Ruby
  
5.Shell
  12.2.5 wirtelines()写入一个序列字符串到文件
>>> f = open('test.txt', 'a')  
>>> f.writelines(['a','b','c'])
  
>>> f.flush()
  
# cat test.txt
  
1.Python
  
2.Java
  
3.C++
  
4.Ruby
  
5.Shell
  
abc
  12.2.6 seek()从指定位置读取
>>> f = open('test.txt', 'r')  
>>> f.tell()
  
0
  
>>> f.seek(9)
  
>>> f.tell()
  
9
  
>>> f.seek(5,1)  # 1表示从当前位置开始
  
>>> f.tell()
  
14
  
  12.2.7 tell()返回当前指针位置
>>> f = open('test.txt', 'r')  
>>> f.tell()
  
0
  
>>> f.readline()
  
'1.Python\n'
  
>>> f.tell()
  
9
  
>>> f.readline()
  
'2.Java\n'
  
>>> f.tell()
  
16
  
>>> f.close()  # 使用完后关闭文件
  
  
  博客地址:http://lizhenliang.blog.51cto.com
  QQ群:323779636(Shell/Python运维开发群)
  
  12.3 文件对象增删改查
  在shell中,我们要想对文件指定行插入内容、替换等情况,使用sed工具很容易就实现。在本章节讲的open()函数并没有直接类似与sed工具的方法,要想实现这样的操作,变通的处理能到达此效果,主要思路是先读取内容修改,再写会文件,以下举几个常用的情况 。
  12.3.1 在第一行增加一行
  例如:在开头添加一个test字符串
#!/usr/bin/python  
# -*- coding: utf-8 -*-
  
f = open('test.txt', 'r')
  
data = f.read()
  
data = "test\n" + data
  
f = open('test.txt', 'w')
  
f.write(data)
  
f.flush()
  
f.close()
  

  
# python test.py
  
# cat test.txt
  
test
  
1.Python
  
2.Java
  
3.C++
  
4.Ruby
  先将数据读出来,然后把要添加的test字符串拼接到原有的数据,然后在写入这个文件。
  12.3.2 在指定行添加一行
  例如:在第二行添加一个test字符串
#!/usr/bin/python  
# -*- coding: utf-8 -*-
  
f = open('test.txt', 'r')
  
data_list = f.readlines()  # 经测试,此方法比下面迭代效率高
  
# data_list = []
  
# for line in f:
  
#     data_list.append(line)
  
data_list.insert(1, 'test\n')
  
# data = ''.join(data)
  
f = open('test.txt', 'w')
  
# f.write(data)
  
f.writelines(data_list)
  
f.flush()
  
f.close
  

  
# python test.py
  
# cat test.txt
  
1.Python
  
test
  
2.Java
  
3.C++
  
4.Ruby
  先将数据以列表存储,就可以根据下标插入到指定位置,也就是哪一行了。再通过join把列表拼接成字符串,最后写到文件。
  12.3.3 在匹配行前一行或后一行添加test字符串
#!/usr/bin/python  
# -*- coding: utf-8 -*-
  
f = open('test.txt', 'r')
  
data_list = f.readlines()
  
data_list.insert(2-1, 'test\n')  # 在指定行减去一行就是上一行了,下一行插入同理
  
f = open('test.txt', 'w')
  
f.writelines(data_list)
  
f.flush()
  
f.close
  12.3.4 删除指定行
  例如:删除第三行,与在指定行添加同理
#!/usr/bin/python  
# -*- coding: utf-8 -*-
  
f = open('test.txt', 'r')
  
data_list = f.readlines()
  
data_list.pop(2)
  
f = open('test.txt', 'w')
  
f.writelines(data_list)
  
f.flush()
  
f.close
  例如:只保留第一行至第三行
#!/usr/bin/python  
# -*- coding: utf-8 -*-
  
f = open('test.txt', 'r')
  
data_list = f.readlines()[0:2]  # 列表切片
  
f = open('test.txt', 'w')
  
f.write(data_list)
  
f.flush()
  
f.close
  12.3.5 删除匹配行
  例如:删除匹配Py字符的行
#!/usr/bin/python  
# -*- coding: utf-8 -*-
  
f = open('test.txt', 'r')
  
data = f.readlines()
  
# data_list = []
  
# for line in data:
  
#     if line.find('Py') == -1:   # 如果当前行不包含Py字符,会返回-1,否则返回下标
  
#         data_list.append(line)
  
data_list = [line for line in data if line.find('Py') == -1]
  
f = open('test.txt', 'w')
  
f.writelines(data_list)
  
f.flush()
  
f.close
  12.3.6 全局替换字符串
#!/usr/bin/python  
# -*- coding: utf-8 -*-
  
f = open('test.txt', 'r')
  
data = f.read()
  
data.replace('old string', 'new string')
  
f = open('test.txt', 'w')
  
f.write(data)
  
f.flush()
  
f.close
  12.3.7 在指定行替换字符串
  例如:将C++改为C#
#!/usr/bin/python  
# -*- coding: utf-8 -*-
  
f = open('test.txt', 'r')
  
data = f.readlines()
  
data_list = []
  
for line in data:
  
    if data.index(line) == 2:
  
        data_list.append(line.replace('++', '#'))
  
    else:
  
        data_list.append(line)
  
f = open('test.txt', 'w')
  
f.writelines(data_list)
  
f.flush()
  
f.close
  12.3.8 处理大文件
  在读取上G文件时,直接读取所有内容会导致内存占用过多,内存爆掉。要想提高处理效率,有以下两种方法:
  方法1:open()打开文件返回的对象本身就是可迭代的,利用for循环迭代可提高处理性能
>>> f = open('test.txt')  
>>> for line in f:
  
...   print line   # 每行后面会有一个换行符\n,所以会打印出来换行符,可以使用line.strip('\n')去除
  
...
  
1.Python
  
2.Java
  
3.C++
  
4.Ruby
  方法2:每次只读取固定字节
#!/usr/bin/python  
# -*- coding: utf-8 -*-
  
f = open('test.txt')
  
while True:
  
    data = f.read(1024)  # 每次只读取1024字节
  
    if not data: break
  12.3.9 下载文件
方法1:  
import urllib
  
url = "http://nginx.org/download/nginx-1.10.1.tar.gz"
  
urllib.urlretrieve(url, "nginx-1.10.1.tar.gz")
  

  
方法2:
  
import urllib2
  
url = "http://nginx.org/download/nginx-1.10.1.tar.gz"
  
f = urllib2.urlopen(url).read()
  
with open("nginx-1.10.1.tar.gz", "wb") as data:
  
    data.write(f)
  12.4 fileinput
  fileinput模块是Python内建模块,用于遍历文件,可对多文件操作。
  方法
  描述
fileinput.input([files[, inplace[, backup[, mode[, openhook]]]]])  files:文件路径,多文件这样写['1.txt,'2.txt'']
  inplace:是否将标准输出写到原文件,默认是0,不写
  backup:备份文件扩展名,比如.bak
  mode:读写模式,默认r,只读
  openhook:
fileinput.isfirstline()检查当前行是否是文件的第一行fileinput.lineno()返回当前已经读取行的数量fileinput.fileno()返回当前文件数量fileinput.filelineno()返回当前读取行的行号fileinput.filename()返回当前文件名  12.4.1 遍历文件内容
#!/usr/bin/python  
# -*- coding: utf-8 -*-
  
import fileinput
  
for line in fileinput.input('test.txt'):
  
    print line
  

  
# python test.py
  
1.Python
  
2.Java
  
3.C++
  
4.Ruby
  12.4.2 返回当前读取行的行号
#!/usr/bin/python  
# -*- coding: utf-8 -*-
  
import fileinput
  
for line in fileinput.input('test.txt'):
  
    print fileinput.filelineno()
  
    print line,  # 逗号忽略换行符
  

  
# python test.py
  
1
  
1.Python
  
2
  
2.Java
  
3
  
3.C++
  
4
  
4.Ruby
  12.4.3 全局替换字符,修改原文件
#!/usr/bin/python  
# -*- coding: utf-8 -*-
  
import fileinput
  
for line in fileinput.input('test.txt', backup='.bak', inplace=1):
  
    line = line.replace('++','#')
  
    print line,
  先把要操作的文件备份一个以.bak的后缀文件,inplace=1是将标准输出写到原文件,也就是这个脚本如果没有标准输出,就会以空数据写到原文件。
  12.4.4 对多文件操作
#!/usr/bin/python  
# -*- coding: utf-8 -*-
  
import fileinput
  
for line in fileinput.input(['test.txt', 'test2.txt']):
  
    print line,
  
12.4.5 实时读取文件新增内容,类似tail -f
  
#!/usr/bin/python
  
# -*- coding: utf-8 -*-
  
with open('access.log') as f:
  
     f.seek(0,2)   # 每次打开文件都将文件指针移动到末尾
  
     while True:
  
         line = f.readline()
  
         if line:
  
             print line,
  这个死循环会一直执行下面的操作。很消耗性能。
  我们可以加个休眠,每秒读取一次:
#!/usr/bin/python  
# -*- coding: utf-8 -*-
  
import time
  
with open('access.log') as f:
  
     f.seek(0,2)
  
     while True:
  
         line = f.readline()
  
         if line:
  
             print line,
  
         else:
  
             time.sleep(1)
  12.5 shutil
  shutil模块是Python内建模块,用于文件或目录拷贝,归档。
  方法
  描述
shutil.copyfile(src, dst)复制文件shutil.copytree(src, dst)复制文件或目录shutil.move(src, dst)移动文件或目录shutil.rmtree(path,ignore_errors=False, onerror=None)递归删除目录。os.rmdir()不能删除有文件的目录,就可以用这个了shutil.make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, dry_run=0, owner=None, group=None, logger=None)  Python2.7以后才有这个方法。
  功能是创建zip或tar归档文件。
  base_name:要创建归档文件名
  format:归档文件格式,有zip、tar、bztar、gztar
  root_dir:要压缩的目录
  base_dir:?
  用法:shutil.make_archive('wp','zip','/root/wordpress')
  12.6 with语句
  在处理一些事务时,可能会出现异常和后续的清理工作,比如读取失败,关闭文件等。这就用到了异常处理语句try...except,如下:
#!/usr/bin/python  
# -*- coding: utf-8 -*-
  
f = open('test.txt')
  
try:
  
    data = f.read()
  
finally:
  
    f.close()
  Python对于这种情况提供了一种更简单的处理方式,with语句。处理一个文件时,先获取一个文件句柄,再从文件中读取数据,最后关闭文件句柄。如下:
#!/usr/bin/python  
# -*- coding: utf-8 -*-
  
with open('test.txt') as f:
  
    data = f.read()
  可见这种方式显得更简约,一些异常、清理工作都交给with处理了。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-546315-1-1.html 上篇帖子: python实战系列之通过libvirt操作KVM(六) 下篇帖子: python 日期函数
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表