茫然间,学习到了第九章。
文件只是连续的字节序列。数据的传输经常会用到字节流,无论字节流是由单个字节还是大块数据组成。
9.2 文件内建函数open()和file()
file_object =open(file_name, access_mode = "r", buffering = -1)
如果open失败,则返回IOError异常。
file和open的功能一模一样,可以互换。
9.3 文件内建方法
read()方法用来直接读取字节到字符串中,最多读取给定数目个字节。如果没有给定size参数(默认值为-1)或者size为负,文件将被读取至末尾。
readline()方法读取打开文件的一行。然后整行,包括行结束符,作为字符串返回。和read一样有个参数size,返回size个字节。
readlines()读取所有的行,并作为字符串返回。也有个参数size,代表读取的最大字节数。
写入方法write(), writeline()类似于read(),readline()等函数
核心笔记:保留行分隔符
当使用输入方法如read()或者readlines()从文件中读取行时,python并不会删除行结束符。请看下面的例子:
>>> data = [line forline in open("data.txt").readlines()] >>> data ['hello world i love\n', 'thisworld\n', 'and i love \n', 'python too'] >>> data = [line.strip()for line in open("data.txt").readlines()] >>> data ['hello world i love', 'thisworld', 'and i love', 'python too']
9.3.3 文件内移动
seek()方法可以在文件中移动文件指针到不同的位置。offset字节代表相对于某个位置偏移量。位置的默认值为0,代表从文件开头算起,1代表从当前位置算起,2代表从文件末尾算起。
text()方法表示当前文件指针在文件中的位置--从文件起始算起,单位为字节
文件后面的内容貌似关系到OS模块,内容挺多的,但是目前倒没什么想看的冲动。。。。。
看看文件系统吧。
文件处理:
mkfifo()/mknod() 创建命名管道/创建文件系统节点
remove()/unlink() delete file 删除文件
rename()/ renames() 重命名文件
stat() 返回文件信息
symlink() 创建符号链接
utime() 更新时间戳
tmpfile() 创建并打开(“w+b”)一个新的临时文件
walk() 生成一个目录树下的所有文件名
目录/文件夹
chdir()/fchdir() 改变当前工作目录/通过一个文件描述符改变当前工作目录
chroot() 改变当前进程的根目录
listdir() 列出指定目录的文件
getcwd()/getcwdu() 返回当前工作目录/功能相同,但返回一个unicode对象
mkdir()/makedirs() 创建目录/创建多层目录
rmdir()/removedirs() 删除目录/删除多层目录
访问/权限
access() 检验权限模式
chmod() 改变权限模式
chown()/lchown() 改变owner和group id/功能相同,但不会跟踪链接
umask() 设置默认权限模式
文件描述符操作
open() 底层的操作系统open(对于文件,使用标准的内建open()函数)
read()/write() 根据文件描述符读取/写入数据
dup()/dup2() 复制文件描述符号/功能相同,但是是复制到另一个文件描述符
设备号
makedev() 从major和minor设备号创建一个原始设备号
major()/minor() 从原始设备号获得major/minor设备号
os.path模块中的路径名访问函数
分隔
basename() 去掉目录路径,返回文件名
dirname() 去掉文件名,返回目录路径
join() 将分离的各部分组合成一个路径名
split() 返回(dirname(), basename())元祖
splitdrive() 返回(drivename, pathname)元祖
splitext() 返回(filename,extension)元祖
信息
getatime() 返回最近访问时间
getctime() 返回文件创建时间
getmtime() 返回最近文件修改时间
getsize() 返回文件大小(以字节为单位)
查询
exists() 指定路径是否存在
isabs() 指点路径是否为绝对路径
isdir() 指定路径是否存在且为一个目录
isfile() 指定路径是否存在且为一个文件
islink() 指定路径是否存在且为一个符号链接
ismount() 指定路径是否存在且为一个挂载点
samefile() 两个路径名是否指向同个文件
对于这些操作,需要实地进行才行。
直接做练习吧。
9.11 练习
9–1. 文件过滤. 显示一个文件的所有行, 忽略以井号( # )开头的行. 这个字符被用做Python , Perl, Tcl, 等大多脚本文件的注释符号.
附加题: 处理不是第一个字符开头的注释.
with open("data.txt") as fobj: for eachline in fobj: if not eachline.startswith("#"): print eachline附件题看不懂。。。。。
9–2. 文件访问. 提示输入数字 N 和文件 F, 然后显示文件 F 的前 N 行.
filename = raw_input("please enter the filename:") num = int(raw_input("please enter the line number:")) for eachline in open(filename): if num: print eachline num -= 1 else: break程序输出:
>>> please enter the filename:data.txt please enter the line number:5 #第一行 hello world #第二行 i love this world #第三行
filename = raw_input("please enter the filename:") print len([line for line in open(filename)])程序输出:
>>> please enter the filename:data.txt 8
with open("data.txt","a+") as fobj: for i in range(100): fobj.write(str(i)) fobj.write("\n") with open("data.txt") as fobj: num = 1 for eachline in fobj: if num % 26 != 0: print eachline, num += 1 else: go = raw_input("continue(c to continue, other to quit):") num += 1 if go != "c": break
9–6. 文件比较. 写一个比较两个文本文件的程序. 如果不同, 给出第一个不同处的行号和列号.
fobj1 = open("data1.txt") fobj2 = open("data2.txt") lines1 = fobj1.readlines() lines2 = fobj2.readlines() for i in range(min(len(lines1), len(lines2))): if lines1[i] != lines2[i]: print i break
这道题我没看懂,如何解析???
9–9. Python 文档字符串. 进入 Python 标准库所在的目录. 检查每个 .py 文件看是否有__doc__ 字符串, 如果有, 对其格式进行适当的整理归类. 你的程序执行完毕后, 应该会生成一个漂亮的清单. 里边列出哪些模块有文档字符串, 以及文档字符串的内容. 清单最后附上那些没有文档字符串模块的名字.
附加题: 提取标准库中各模块内全部类(class)和函数的文档.
这道题忽悠了我一个晚上。第一:根本就不存在__doc__的字符串,当我们运行模块.__doc__的时候,实际上是读取开头的字符串。所以我们要判断是开头是否存在“”“字符串”“”这样的格式。
程序如下:
import os import sys num = [] """将所有路径文件名全部提出出来""" def fun(dirName): for i in os.listdir(dirName): if os.path.isdir(dirName + "\\" + i): fun(dirName + "\\" + i) else: num.append(dirName + "\\" + i) fun(r"C:\Python27\Lib") hasDoc = False strTemp = "" fileobj1 = open("hasdoc.txt","a+") fileobj2 = open("nodoc.txt","a+") for i in num: fobj = open(i) for eachline in fobj: if (not hasDoc) and eachline.startswith('"""'): hasDoc = True elif hasDoc and eachline.startswith('"""'): hasDoc = False strTemp += eachline break if hasDoc: strTemp += eachline else: break if strTemp != "": fileobj1.write("文件名:" + i + "\n") fileobj1.write("__doc__ is:" + "\n") fileobj1.write(strTemp + "\n") else: fileobj2.write("文件名:" + i + "\n") strTemp = "" fobj.close() fileobj1.close() fileobj2.close()今天头好疼!!真的好疼,一点看书的欲望都没有。
最近还花了点时间学习wxpython,专门用来对付习题9-10,9-11这种图形界面的设计,但是发现学习的蛋疼,可能我这人不太喜欢用UI这些东西吧。
所以,习题9-10,9-11,9-12就不做了。
9–13. 命令行参数
a) 什么是命令行参数, 它们有什么用?
b) 写一个程序, 打印出所有的命令行参数.
a)跟随着命令写入的参数,主要用于linux下运行程序
#coding=utf-8 import sys for i in range( 1, len( sys.argv ) ): print "parameter %d : %s" % ( i, sys.argv[i] )程序输入输出:
习题9-14
# coding=utf-8 """计算器程序,模仿内建函数eval()""" import sys import os def new_eval( num ): if num[1] == "+": return int( num[0] ) + int( num[2] ) elif num[1] == "-": return int( num[0] ) - int( num[2] ) elif num[1] == "*": return int( num[0] ) * int( num[2] ) elif num[1] == "/": return int( num[0] ) / int( num[2] ) elif num[1] == "%": return int( num[0] ) % int( num[2] ) elif num[1] == "**": return int( num[0] ) ** int( num[2] ) else: return "error operator" if __name__ == "__main__": if sys.argv[1:][0] == "print": with open( "result.txt" ) as fobj: print fobj.read() os.remove("result.txt") else: with open( "result.txt", "a+" ) as fobj: fobj.write("".join(sys.argv[1:])) fobj.write("\n") fobj.write( str(new_eval( sys.argv[1:] ) )) fobj.write("\n") print "the result is : %d" % ( new_eval( sys.argv[1:] ) )不要小看任何一个小程序,这段代码我写了很久,很多细节的东西都没有掌握,也可能是太久没写python代码的缘故吧。
程序输入输出:
9–15. 复制文件. 提示输入两个文件名(或者使用命令行参数). 把第一个文件的内容复制到第二个文件中去.
# coding=utf-8
file1 = raw_input( "please enter file1:" )
file2 = raw_input( "please enter file2:" )
with open( file1 ) as fobj1:
with open( file2 , "w" ) as fobj2:
for i in fobj1:
fobj2.write( i )
with open(file2) as fobj2:
print fobj2.read()
程序输入输出:
>>> please enter file1:hello.txt please enter file2:world.txt hello world 无论如何,都要坚持下去 加油
import os file1 = raw_input("please enter the file:") with open(file1) as fobj1: with open("temp.txt","w") as fobj2: for i in fobj1: if len(i) > 80: num = list(i) count = len(num) / 80 for i in range(count): fobj2.write("".join(num[:79])) fobj2.write("\n") num = num[79:] fobj2.write("".join(num)) else: fobj2.write(i) fobj2.write("\n") with open("temp.txt") as fobj2: with open(file1,"w") as fobj1: for i in fobj2: fobj1.write(i) os.remove("temp.txt")
class fileEdit(object): def newFile(self, fileName, fileText): with open(fileName, "a+") as fobj: fobj.write(fileText) def showFile(self, fileName): strTemp = "" with open(fileName) as fobj: for i in fobj: strTemp += i return strTemp def editFile(self, fileName, lineNum, newText): lines = [] with open(fileName) as fobj: lines = fobj.readlines() if lineNum > len(lines): return False lines[lineNum - 1] = newText with open(fileName,"w") as fobj: fobj.writelines(lines) if __name__ == "__main__": while True: fobj = fileEdit() print "n to newfile" print "s to showfile" print "e to editfile" print "and q to quit file" choice = raw_input("please enter the choice:") if choice.lower() == "q": break if choice.lower() not in ["n","s","e"]: continue else: if choice.lower() == "n": fileName = raw_input("please enter the filename:") fileText = "" while True: Text = raw_input("please enter the text(q to quit):") if Text.lower() == "q": break fileText += Text fileText += "\n" fobj.newFile(fileName, fileText) elif choice.lower() == "s": fileName = raw_input("please enter the filename:") print fobj.showFile(fileName) elif choice.lower() == "e": fileName = raw_input("please enter the filename:") lineNum = int(raw_input("please enter the lineNumber:")) lineText = raw_input("please enter the newText:") fobj.editFile(fileName, lineNum, lineText)程序输入输出:
>>> n to newfile s to showfile e to editfile and q to quit file please enter the choice:n please enter the filename:hello.txt please enter the text(q to quit):hello world please enter the text(q to quit):i love this world please enter the text(q to quit):and i love python too please enter the text(q to quit):q n to newfile s to showfile e to editfile and q to quit file please enter the choice:e please enter the filename:hello.txt please enter the lineNumber:3 please enter the newText:i love you n to newfile s to showfile e to editfile and q to quit file please enter the choice:s please enter the filename:hello.txt hello world i love this world i love you n to newfile s to showfile e to editfile and q to quit file please enter the choice:q
fileName = raw_input("please enter the fileName:") fileCh = raw_input("please enter the character:") countNum = 0 with open(fileName) as fobj: for i in fobj: countNum += i.count(fileCh) print "character %s occurs:%d" % (fileCh, countNum)程序输入输出:
>>> please enter the fileName:hello.txt please enter the character:l character l occurs:6
想了半天,解决方法倒是有,但是不知道怎么去写。
import os import random def fun(ch, countNum, length): firstLength = length num = [] while firstLength - countNum: chara = random.choice(xrange(255)) if ch == chara: continue else: num.append(chara) firstLength -= 1 for i in range(countNum): num.append(ch) new_num = [] while length: i = int(random.random() * length) new_num.append(num[i]) del num[i] length -= 1 return new_num if __name__ == "__main__": num = fun(25, 10, 15) for item in num: print "{0:b}".format(item)程序显示,二进制25将会被现实10次,而且是随机排列的:
>>> 1100011 11001 11001 11001 11001 11001 10111 11101000 100100 11001 11001 10000101 11001 11001 11001
import zipfile with zipfile.ZipFile("hello.zip","w") as myzip: myzip.write("hello.txt")
这道题,坦白说不会。从Google上很容易找到答案,然后找到答案后好好研究一遍。
import os import zipfile def zipdir(path, zip): for root, dirs, files in os.walk(path): for file in files: zip.write(os.path.join(root, file)) if __name__ == '__main__': zip = zipfile.ZipFile('Python.zip', 'w') zipdir('C:\\Python27\\', zip) zip.close()整体思想和上面的一致,只是增加了路径的查询罢了。