Python文件操作是Python编程的基础,其实不难和C语言很像。内容无非分为几大块:
- 新建文件/目录
- 删除文件/目录
- 使用文件/得到目录
- 复制/移动文件
- 判断文件/目录
- 获得文件信息
0、前提
所有后续操作,应该先导入os模块(os是小写),即:
- import os
1、新建文件/目录
(1)创建文件
第一种方法是使用os模块内置方法mknod创建节点,mkfilo是创建管道。但是3.3版本下,我尝试用它来创建空文件,失败:
- >>> import os
- >>> mknod('newfile')
- Traceback (most recent call last):
- File "", line 1, in module>
- mknod('newfile')
- NameError: name 'mknod' is not defined
- >>> os.mknod('newfile')
- Traceback (most recent call last):
- File "", line 1, in module>
- os.mknod('newfile')
- AttributeError: 'module' object has no attribute 'mknod'
我不知道是因为什么原因,在网上查找也没有结果。我将去CU论坛里求助,有了结果会尽快更新博客的。大家要是知道的话,可以直接回复本文。
感谢yk325对我的启发。
第二种方式,比较常用。和C一样,参数都一样:
open("test.txt",w),该方法将直接打开一个文件,如果文件不存在则创建文件
关于open 模式:
w:写打开
a:追加打开(从 EOF 开始, 必要时创建新文件)
r:读打开,如果open("this.txt")这种写法,默认就是r
r+:读写打开
w+:读写打开
a+:读写打开
rb、wb、ab:二进制模式
rb+、wb+、ab+:二进制读写模式打开
(2)创建目录
如果知道父目录,只是在其下创建一个子目录的话,容易:
- >>> os.mkdir(r"C:\Users\lk\Desktop\python\No1")
- >>> os.makedirs(r"C:\Users\lk\Desktop\python\No1\No2\No3\No4")
2、删除文件/目录
(1)删除文件
删除文件使用的是os.remove(不是move),如下例所示
- >>> os.remove(r"C:\Users\lk\Desktop\python\test3.txt")
- >>> os.remove(r"C:\Users\lk\Desktop\python\No1")
- Traceback (most recent call last):
- File "", line 1, in module>
- os.remove(r"C:\Users\lk\Desktop\python\No1")
- PermissionError: [WinError 5] 拒绝访问。: 'C:\\Users\\lk\\Desktop\\python\\No1'
使用remove删除文件,不论文件是否为空都可以。但它不能用来删除目录,否则拒绝访问。
(2)删除目录
删除空目录,使用rmdir。当然你肯定不过瘾,怎样全删呢,不管有多少个子目录,里面又含有多少文件,用rmtree搞定。想使用rmtree,它并不在os标准包中,所以还需要shutil包:
- >>> os.rmdir(r"C:\Users\lk\Desktop\python\No1\No2\No3\No4")
- >>> import shutil
- >>> shutil.rmtree(r"C:\Users\lk\Desktop\python\No1")
3、使用文件/进入目录
(1)使用文件
这里使用的意思是读取、写入和追加。
先来看读。是的没错,在家吃冰箱里的冷饮前提是家里首先要有冰箱。读前需要确保文件已经打开,然后使用read()、readline()、readlines()方法即可,区别在于readline()将从当前位置读取一行并以“/n”结尾(麻烦的是很多行末已经是“/n”结尾罗,所以可以预想,将产生很多空行),readlines()接着没读完的读完,负责把剩下的内容全部一次性读出来组成字符串列表返回,而read()则从头到尾整体读出到一个长长的字符串中。
再来看写,写很简单,用write()写入就可以罗。写完了可以close关闭文件,内容便保存起来了。
- >>> myfile = open(r"C:\Users\lk\Desktop\python\Test.txt",'w+')
- >>> myfile.write("""
- 五岳之巅
- 滚雷执闪劈裂天,
- 怒对风狂山涧间。
- 脚踩神魔百尺潭,
- 头举妖仙万韧山。
- 荆棘塞途奈我何,
- 断崖绝路又何难?
- 有朝一日登高处,
- 万卷浮云任尔翻。
- """)
- 80
- >>> myfile.close()
- >>> myfile = open(r"C:\Users\lk\Desktop\python\Test.txt",'r')
- >>> myfile.readline()
- '\n'
- >>> myfile.readline()
- '五岳之巅\n'
- >>> myfile.readlines()
- ['\n', '滚雷执闪劈裂天,\n', '怒对风狂山涧间。\n', '脚踩神魔百尺潭,\n', '头举妖仙万韧山。\n', '\n', '荆棘塞途奈我何,\n', '断崖绝路又何难?\n', '有朝一日登高处,\n', '万卷浮云任尔翻。\n']
- >>> myfile.seek(0,0)
- 0
- >>> myfile.read()
- '\n五岳之巅\n\n滚雷执闪劈裂天,\n怒对风狂山涧间。\n脚踩神魔百尺潭,\n头举妖仙万韧山。\n\n荆棘塞途奈我何,\n断崖绝路又何难?\n有朝一日登高处,\n万卷浮云任尔翻。\n'
两种解决方案:
第一种,笨办法,打开文件,每次读一行,遇到2-3/4-5就删一个“\n”:
- import os
- f = open(r"C:\Users\lk\Desktop\python\Test.txt",'r')
- h = open(r"C:\Users\lk\Desktop\python\Result.txt",'w+')
- #i为行号变量
- i = 1
- #j为修改类型,1为删除,0为不变
- j = [1,1,0,1,0,1,0,0,1,0,1,0,1,0]
- for i in range(0,len(j)):
- s = f.readline()
- if j[i]:
- s = s[:-1]
- h.write(s)
- i = i + 1
- f.close()
- #重新读取j
- h.seek(0,0)
- h.read()
- h.close()
第二种,搜“,”,逗号下一个“\n”删之即可。这个方法很好,简单,高效。哈哈。
- import os
- f = open(r"C:\Users\lk\Desktop\python\Test.txt",'r')
- h = open(r"C:\Users\lk\Desktop\python\Result.txt",'w+')
- str = f.read()
- s = str.split(',')
- str = s[0][1:]
- for i in range(1,len(s)):
- str = str +','+ s[i][1:]
- i = i + 1
- h.write(str)
- f.close()
- h.close()
最后还有个追加问题,追加的方法是用open(xxx,'a')来控制,用a打开的文件默认就是seek(2,0)游标处于文件尾。还是举例:
- import os
- f = open(r"C:\Users\lk\Desktop\python\Result.txt",'a+')
- str = "\n作者:五岳之巅,2011年1月14日,13点于榴花\n"
- f.write(str)
- f.close()
最近我在看《数学之美》这本书,我在想对于每一行我们可以使用len(readline())进行测量并统计,不过真实世界中经常是整段统计,是按自然段落统计而非行统计,搜索引擎就是这样,对于不同位置的段还赋予不同的权重,比如第一自然段和最后一自然段权重较高。
我的问题是如何用Python简单地统计一篇文章段落的词数?
要解决的关键问题就只有一个,即“什么是段落?”答:必须满足连续文字前后两个“\n”之间的就是段落。于是我写了如下的代码,也赶了个时髦,统计莫言《蛙》的第一部第一章的自然段,并输出统计内容。原文如下:
使用如下代码:
- import os
- f = open(r"C:\Users\lk\Desktop\python\wa.txt",'r')
- #r保存结果
- r = {}
- paper = (f.read()).split('\n\n')
- num = 1
- for i in paper:
- r[num] = len(i)
- num = num + 1
- f.close()
- #range(1,num)是不包含num的
- for key in range(1,num):
- print("第%s自然段:共有%d个字\n"%(key,r[key]))
- >>>
- 第1自然段:共有250个字
- 第2自然段:共有130个字
- 第3自然段:共有2566个字
- 第4自然段:共有409个字
- 第5自然段:共有87个字
(2)得到目录
访问目录的操作主要是获得指定目录及从文件路径中得到相关信息。
对目录进行操作,Python把这些功能都封装到path模块中,对于不同的操作系统Python可以使用相同的方法,这便使得程序移植变得更加容易。
了解os.path模块,要从了解当前目录名和文件名入手,这分为两种情况:
1)已知一个目录
如果给定一个目录,那么我们可以使用os.path.basename()方法获得文件名,而使用os.path.dirname()获取文件前的路径。
- >>> import os.path
- >>> filepath = r'C:\Users\lk\Desktop\Python编程入门经典.pdf'
- >>> os.path.basename(filepath)
- 'Python编程入门经典.pdf'
- >>> os.path.dirname(filepath)
- 'C:\\Users\\lk\\Desktop'
OK,接下来是几种常用用法,splitdrive()取得根目录或磁盘盘符(视操作系统而定,Linux下我还没试,不知道是不是),split()分解出路径和文件全名,这时可用许多变量分别存储返回的元组中相对应的值,splitext()也是拆分并返回元组,但它最后一个值不是文件名而是文件扩展名。
- >>> os.path.splitdrive(filepath)
- ('C:', '\\Users\\lk\\Desktop\\Python编程入门经典.pdf')
- >>> os.path.splitdrive('/home/lk/document/ok.py')
- ('', '/home/lk/document/ok.py')
- >>> os.path.split(filepath)
- ('C:\\Users\\lk\\Desktop', 'Python编程入门经典.pdf')
- >>> a,b = os.path.split(filepath)
- >>> print(a)
- C:\Users\lk\Desktop
- >>> print(b)
- Python编程入门经典.pdf
- >>> a,b = os.path.splitext(filepath)
- >>> print(a)
- C:\Users\lk\Desktop\Python编程入门经典
- >>> print(b)
2)得到当前目录
如果现在你不知道你当前执行程序的路径在哪里该怎么办?好办,Python的os模块自带了getcwd()。准备no1.py文件:
在终端执行os.getcwd(),随后执行程序no1.py,请看结果:
- >>> os.getcwd()
- 'C:\\Python33'
- >>> ================================ RESTART ================================
- >>>
- 程序no1.py当前路径是:C:\Users\lk\Desktop\python
- >>>
(3)访问目录
访问目录的操作主要是进入目录、跳出目录和列出当前目录内容。
进入、跳出目录,并非像OS Shell那样与人交互,使用cd命令进入某层目录。获取目录中的内容使用os.listdir()。接着刚才的例子:
- >>>
- 程序no1.py当前路径是:C:\Users\lk\Desktop\python
- >>> os.listdir()
- ['blogtest.py', 'chapter8.py', 'mydoc.docx', 'no1.py', 'no2.py', 'no3.py', 'no4.py', 'no5.py', 'qewqeq.txt', 'Result.txt', 'temp.txt', 'Test.txt', 'test2.txt', 'wa.txt']
- >>> os.mkdir('newdir')
- >>> os.listdir()
- ['blogtest.py', 'chapter8.py', 'mydoc.docx', 'newdir', 'no1.py', 'no2.py', 'no3.py', 'no4.py', 'no5.py', 'qewqeq.txt', 'Result.txt', 'temp.txt', 'Test.txt', 'test2.txt', 'wa.txt']
那么目录如何合成呢?很容易,目录就是字符串,合成目录就是合成字符串,可以使用os.path.join:
- >>> os.getcwd()
- 'C:\\Users\\lk\\Desktop\\python'
- >>> a,b = os.path.split(os.getcwd())
- >>> print(a)
- C:\Users\lk\Desktop
- >>> print(b)
- python
- >>> c = "论文"
- >>> otherdir = os.path.join(a,c)
- >>> os.listdir(otherdir)
- ['_云计算_下的图书馆发展策略研究.kdh', '云计算XaaS概念簇的层次模型研究.doc', '云计算_图书馆事业发展的机遇与挑战.kdh', '从OCLC看图书馆云计算的未来.kdh', '博士', '基于云计算的图书馆IT应用探讨.kdh', '基于云计算的图书馆信息平台的构建.caj', '已读', '情报学报.xls', '我国云计算和图书馆相关问题研究综述.caj']
(4)改变目录
现在来看看如何改变目录,前面说过了python的os.getcwd()是获取当前工作目录,即当前python脚本工作的目录路径。
而os.chdir()则用来改变当前脚本工作目录,os.curdir用于返回当前目录,值得一提的是 os.pardir用以获取当前目录的父目录字符串名。试试吧:
- >>> os.curdir
- '.'
- >>> os.path.pardir
- '..'
- >>> os.chdir(r'd:/')
- >>> os.listdir()
- ['$RECYCLE.BIN', '123', '360Downloads', 'Boot', 'bootmgr', 'BOOTSECT.BAK', 'foiu.ld', 'FSGLD', 'grldr', 'Media', 'Program Files', 'System Volume Information']
- >>>
(4)递归目录
现在来看看如何改变目,使用递归让自己解决自己的问题:
- import os
- def dir_tree(dir_path):
- if not os.path.isdir(dir_path):
- print("%s是非法目录"%(dir_path))
- return False
- for name in os.listdir(dir_path):
- fullpath = os.path.join(dir_path,name)
- print(fullpath)
- if os.path.isdir(fullpath):
- dir_tree(fullpath)
- a = r"C:\Users\lk\Desktop\python"
- dir_tree(a)
- >>>
- C:\Users\lk\Desktop\python\blogtest.py
- C:\Users\lk\Desktop\python\chapter8.py
- C:\Users\lk\Desktop\python\mydoc.docx
- C:\Users\lk\Desktop\python\newdir
- C:\Users\lk\Desktop\python\no1.py
- C:\Users\lk\Desktop\python\no2.py
- C:\Users\lk\Desktop\python\no3.py
- C:\Users\lk\Desktop\python\no4.py
- C:\Users\lk\Desktop\python\no5.py
- C:\Users\lk\Desktop\python\no6.py
- C:\Users\lk\Desktop\python\no7.py
- C:\Users\lk\Desktop\python\qewqeq.txt
- C:\Users\lk\Desktop\python\Result.txt
- C:\Users\lk\Desktop\python\temp.txt
- C:\Users\lk\Desktop\python\Test.txt
- C:\Users\lk\Desktop\python\test2.txt
- C:\Users\lk\Desktop\python\top
- C:\Users\lk\Desktop\python\top\middle
- C:\Users\lk\Desktop\python\top\middle\bottom
- C:\Users\lk\Desktop\python\top\middle\bottom\bottom.txt
- C:\Users\lk\Desktop\python\top\middle.txt
- C:\Users\lk\Desktop\python\wa.txt
- >>>
4、复制/移动文件
在python中,移动、复制、重命名一个文件/文件夹是通过shutil模块实现的,在这里结合目录操作,举一个综合的例子:
- import os
- import shutil
- cpath = os.getcwd() #current path
- os.makedirs("top/middle/bottom")
- mpath = os.path.join(cpath,"top/middle/bottom") #modified path
- if os.path.isdir(mpath):
- os.chdir(mpath)
- fname = "bottom.txt"
- fpath = os.path.join(mpath,fname)
- f = open(fpath,'w')
- f.write('this is the end line.')
- f.close()
- if os.path.isfile(fpath):
- shutil.copy(fname,os.path.pardir)
- os.chdir(os.path.pardir)
- shutil.move(fname,"middle.txt")
- fname = "middle.txt"
- fpath = os.path.join(os.getcwd(),fname)
- f = open(fpath,'r+')
- tmpwords = f.read()
- f.seek(0,0)
- f.write("this is the second line.\n"+tmpwords)
- f.close()
- shutil.move(fpath,os.path.pardir)
5、判断文件/目录
以下内容的返回值True,False
exists() 指定路径(文件或者目录)是否存在
isabs() 指定路径是否为绝对路径
isdir() 指定路径是否存在且为一个目录
isfile() 指定路径是否存在且为一个文件
samefile() 两个路径名是否指向同一个文件
- >>> os.listdir(otherdir)
- ['_云计算_下的图书馆发展策略研究.kdh', '云计算XaaS概念簇的层次模型研究.doc', '云计算_图书馆事业发展的机遇与挑战.kdh', '从OCLC看图书馆云计算的未来.kdh', '博士', '基于云计算的图书馆IT应用探讨.kdh', '基于云计算的图书馆信息平台的构建.caj', '已读', '情报学报.xls', '我国云计算和图书馆相关问题研究综述.caj']
- >>> os.path.exists(otherdir)
- True
- >>> os.path.isdir(otherdir+'noname')
- False
- >>> os.path.isfile(otherdir+'基于云计算的图书馆信息平台的构建.caj')
- False
- >>> os.path.isfile(os.path.join(otherdir,'基于云计算的图书馆信息平台的构建.caj'))
- True
- >>>
6、获得文件信息
使用以下方法获取文件相关信息:
getatime() 返回最近访问时间(浮点型秒数)
getctime() 返回文件创建时间
getmtime() 返回最近文件修改时间
getsize() 返回文件大小(字节为单位)
abspath() 返回绝对路径
- >>> filepath = os.path.join(otherdir,'基于云计算的图书馆信息平台的构建.caj')
- >>> os.path.isfile(filepath)
- True
- >>> os.path.getatime(filepath)
- 1345895347.7942
- >>> os.path.getctime(filepath)
- 1345895347.7942
- >>> os.path.getsize(filepath)
- 319364
- >>> print("%dKB"%(os.path.getsize(filepath)/1024))
- 311KB
- >>> os.path.abspath(filepath)
- 'C:\\Users\\lk\\Desktop\\论文\\基于云计算的图书馆信息平台的构建.caj'
五岳之巅原创,如有转载,必须注明出处,谢谢!