知乎:https://www.zhihu.com/people/monkey.d.luffy Android高级开发交流群2: 752871516
全部博文(315)
分类: Python/Ruby
2012-02-22 21:28:03
回忆:在第九章又强调了“保留分隔符“这样的核心笔记,其实在上章已经解释了。其实就是为了不同系统之间文件结束符的统一性。就是\n\r, \n或者其他系统的文件结束符。你懂的!python可以使用strip()内建函数来处理。
1》由于在文件这块,file的read()或者readlines()没有对行结束符进行处理,留给我们自己来做,所以你要自己处理了。
Like this:
f = open('myFile', 'r')
data = [line.strip() for line in f.readlines()]
f.close()
Tip: 到这里还是要提醒下:
就是在读取文件的时候有很多方法,不过为了节省内存的使用我们要考虑高效的方法,不然当文件很大的时候怎么办了?
2》 for eachLine in f.readline():
#而利用迭代的方法应该是不错的,在上一章我们也是利用迭代器表达式来做的
3》行分隔符相关os模块属性(测试了下,还不知道如何使用,我想应该可以作为分割参数传入处理函数,在不同平台下相应的值是不同的,所以可以作为跨平台字符串处理函数的参数来使用,应该是这样的)
>>> import os
>>> os.pardir
'..'
>>> os.curdir
'.'
>>> os.pathsep
':'
>>> os.sep
'/'
>>> os.linesep
'\n'
4》文件操作
4.1》按行写入(由于raw_input()不会保留用户输入的换行符,所以要自己在写入的时候处理,就用到了linesep这个os模块的属性,终于知道可以这样用)
filename = raw_input('Enter file name: ')
fobj = open(filename, 'w')
while True:
aLine = raw_input("Enter a line ('.' to quit): ")
if aLine != ".":
fobj.write('%s%s' % (aLine, os.linesep)
else:
break
fobj.close()
4.2》永久存储模块
理解:为了避免用户重复输入经常使用到的大量数据,这时候我们就需要使用到永久存储模块,但是我还是不太明白,如果用文件应该也是可以永久存储的,除非你删除了它,是吧?不过在看到后面,就发现python为我们提供了存储数据的这种模块,而且是永久,虽然生命周期和磁盘文件类似,不过对于文件的操作我们还需要open()或者file()文件,而且还需要去处理相关操作的细节,比如行结束符,就显得很麻烦了;但是如果我们使用现成模块,就省事了,我觉得有这层意思!
至于里面的很多东西就要自己取理解了,内容不少,不过下面内容可以帮你取联想下具体存储机制:
核心模块: pickle 和 cPickle
你可以使用 pickle 模块把 Python 对象直接保存到文件里, 而不需要把它们转化字符串,也不用底层的文件访问操作把它们写入到一个二进制文件里. pickle 模块会创建一个 Python 语言专用的二进制格式, 你不需要考虑任何文件细节, 它会帮你干净利索地完成读写对象操作, 唯一需要的只是一个合法的文件句柄.
pickle 模块中的两个主要函数是 dump() 和 load() . dump() 函数接受一个文件句柄和一个
数据对象作为参数, 把数据对象以特定格式保存到给定文件里. 当我们使用 load() 函数从文件中
取出已保存的对象时, pickle 知道如何恢复这些对象到它们本来的格式. 我们建议你看一看pickle 和更"聪明"的 shelve 模块, 后者提供了字典式的文件对象访问功能, 进一步减少了程序
员的工作。
核心模块:这是展示了一个用法,其他自己可以尝试,都是文章好啊,讲的挺细
核心提示: 使用 os.path.expanduser() 的波浪号 ( ~ ) 进行扩展
虽然 glob 和 fnmatch 提供了 Unix 样式的模式匹配, 但它们没有提供对波浪号(用户目录)
字符, ~ 的支持. 你可以使用 os.path.expanduser() 函数来完成这个功能, 传递一个带波浪号的
目录, 然后它会返回对应的绝对路径. 这里是两个例子, 分别运行在 Unix 和 Win32 环境下:
>>> os.path.expanduser('~/py')
'/home/wesley/py'
>>> os.path.expanduser('~/py')
'C:\\Documents and Settings\\wesley/py'
另外 Unix 家族系统还支持 "~user" 这样的用法, 表示指定用户的目录. 还有, 注意 Win32
版本函数没有使用反斜杠来分隔目录路径
问题1:文件系统部分,就是C系统编程的时候文件系统的概念,很多关于inode节点的东西,symlink(), dup(), dup2(), 等等,看上去很熟悉了,当初学习c的时候,文件系统那块还是学了很长时间。有时间还是要好好学习C语言。
问题2:文件内建函数和文件内建方法到底是什么区别?
都学习了这么久了,还是迷糊?
看来要了解清楚才行,不然就废柴一个了。
a》文件内建函数[open()和 file()]
工厂函数file()
,类型和类被统一了起来,这时,加入了内建函数 file().
所以就成为了工厂函数。
b》文件内建方法
open() 成功执行并返回一个文件对象之后, 所有对该文件的后续操作都将通过这个"句柄"进
行. 文件方法可以分为四类: 输入, 输出, 文件内移动, 以及杂项操作。
其实我认为其实方法也是一种函数,函数嘛就是为了完成某个操作,返回用户需要的值,不过open()返回一个句柄后,用“句柄”去调用相应的函数,像f.readlines(),去获取数据,那么自然readlines()这样的函数就成为了文件操作的内建方法,毕竟方法是在文件内部来搞的。我认为是这样,不知道对不对?
5》最后关于命令行参数,对于编程了这么多年的你,可能不会经常使用命令参数,但是如果有初学者问你命令行参数有什么用,你能回答的很清楚吗?
From:
命令行参数有用吗? Unix 操作系统中的命令通常会接受输入, 执行一些功能, 然后把结果作为
流输出出来. 这些输出的结果还可能被作为下一个程序的输入数据, 在完成了一些其它处理后, 再把新的输出送到下一个程序, 如此延伸下去. 各个程序的输出一般是不保存的, 这样可以节省大量的磁盘空间, 各个程序的输出通常使用"管道"实现到下个程序输入的转换.
这是通过向命令行提供数据或是通过标准输入实现的. 当一个程序显示或是发送它的输出到标准输出文件时, 内容就会出现在屏幕上 - 除非该程序被管道连接到下一个程序, 那么此时程序的标准输出就成为下个程序的标准输入。
其实学习python还可以复习很多关于C语言的问题?本身python就是调用了大量的C库来实现解释代码的。
6》Exercise:
(还是做点练习,关于zip, tar归档文件的概念,以前都不怎么接触.)
9–20.压缩文件. 写一小段代码, 压缩/解压缩 gzip 或 bzip 格式的文件. 可以使用命令行下的 gzip 或 bzip2 以及 GUI 程序 PowerArchiver , StuffIt , 或 WinZip 来确认你的 Python支持这两个库.
问题:为了完成这个,我找了个网上的代码,发现不行,不知道是参数还是哪出问题,然后自己改也不行了。老是报一些错!
#file: gzip2.py
#!/usr/bin/env python
import gzip
g = gzip.GzipFile(filename = '1.py', mode = 'wb',
compresslevel = 9, fileobj = open(r'test.log.gz','wb'))
g.filename'.gz' #也不对
#g.filename('.gz') #filename不是回调函数
g.write(open(r'test.log').read())
g.close()
ERROR1:
File
"/home/huanglei/python/file/1.py", line 10, in
src = sys.argv[2]
IndexError: list index out of range
原因:郁闷的,原来是说你这个文件路径太长了,悲剧啊,看来还是有bug,将文件拷贝到家目录下就好了。后来全部改了代码后,发现不是这个问题?
ERROR2:
gzip2.py:7: DeprecationWarning: use the name attribute
g.filename'.gz'
Traceback (most recent call last):
File "gzip2.py", line 7,
in
g.filename'.gz'
TypeError: 'str' object is not callable
原因:原来的写法是g.filename'.gz' # 但这显然不对啊
我自己写更不对,字符串不能作为函数来使用????
后面我把那句删去了,真不知道网上哪些转载的哥们试验过没,或者可能我错了。以后或许会更加明白?
最后我弄了下,这样可以的:
/--------------------Compress:----------------------------------------------------------
ANSWER:
#file: gzip2.0.py
#!/usr/bin/env python
import gzip
g = gzip.GzipFile(filename = '1.py', mode = 'wb', compresslevel = 9, fileobj = open(r'test.log.gz','wb'))
g.write(open('1.py').read())
g.close()
/-------------------Encompress:----------------------------------------------------------
#!/usr/bin/env python
import gzip
g = gzip.GzipFile(mode = 'rb', fileobj = open(r'test.log.gz','rb'))
open(r'1.txt', 'wb').write(g.read())
#名字随便
g.close()
其实从上面可执行代码来看,它是事先构造了一个压缩包,里面有个名叫1.py的文件,然后我们在通过g这个对象的write()方法像g这个对象构造的压缩包里面的1.py去写入内容。过程就是这样!
我在测试的时候将g.write的文件写成了test.log,发现根本不对,压缩包文件根本是空的。所以要注意啦。我怎么测试刚开始那个文件都不行,真搞不懂是我的问题,还是..................
9–21.ZIP 归档文件. 创建一个程序, 可以往 ZIP 归档文件加入文件, 或从中提取文件,有可能的话, 加入创建 ZIP 归档文件的功能.
ANSWER1:(添加文件到zip文件,简单了点)
#!/usr/bin/env python
import zipfile
z = zipfile.ZipFile('1_copy.txt.zip', mode = 'a')
z.write('1.txt')
ANSWER2:(可以只是打印,不过中文乱码,不过你解压并且写相应文件后一样)
#file: zip.py
#!/usr/bin/env python
import zipfile
z = zipfile.ZipFile('1_copy.txt.zip', mode = 'r')
f = open('1_copy.txt', 'w')
for eachLine in z.read('1_copy.txt'):
f.write(eachLine)
print eachLine,
最后,还有些练习就不做了,研究这两个练习都搞了好久,网上资料太那个了.....要自己试验成功才敢确定,而且才会有了解.加油...!