http://blog.csdn.net/pipisorry/article/details/37769669
python文件输入输出教程
python文件读取open()
打开文件对象open()
open
(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)¶
得到一个文件对象(file object):open(filename, mode='r')
方法1:最基本的读文件方法
file = open("sample.txt")
line = file.readline()
for line in lines:
pass # do something
一行一行得从文件读数据,显然比较慢;不过很省内存。
函数参数:模式mode
模式 | 描述 |
---|---|
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
w | 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
w+ | 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
还有一个模式U,不过已经完全默认了,不使用了。There is an additional mode character permitted, 'U'
, which no longer has any effect, and is considered deprecated. It previously enabled universal newlines in text mode, which became the default behaviour in Python 3.0.
示例1 python对同一个文件进行读后写(读取文件,修改后再写入)?
1 如果使用w+时,还没读就被刷新覆盖了,文件什么都没了
2 使用r+打开文件后再seek(0)回到文件头进行写
with open(filename, 'r+') as file:
lines = file.read()
lines = re.sub('<configuration>.*</configuration>', s, lines, flags = re.S)
file.seek(0)
file.write(lines)
示例2 文本与二进制方式打开文件的区别
'wb'写入,在py3中是用有编码写入的,所以需要是py3的bytes或者py2的str(如f.write(b' '.join([word, tag, tag_pred]) + b'\n')),文本则没有。但是'wb'写入的,可以直接通过'r', encodeing='utf-8'读取。
word, tag, tag_pred是bytes的话,py3两种方式写入:
with open('results/score/{}.preds.txt'.format(name), 'wb') as f:
f.write(b' '.join([word, tag, tag_pred]) + b'\n')
或者
with open('results/score/{}.preds.txt'.format(name), 'w', encoding='utf-8') as f:
f.write(' '.join([word.decode('utf-8'), tag.decode('utf-8'), tag_pred.decode('utf-8')]) + '\n')
Windows平台下 :
如果以“文本”方式打开文件,当读取文件的时候,系统会将所有的"/r/n"转换成"/n";当写入文件的时候,系统会将"/n"转换成"/r/n"写入。
如果以"二进制"方式打开文件,则读/写都不会进行这样的转换。
lines may be terminated by any of the following: the Unix end-of-line convention ’\n’, the Macintosh convention ’\r’, or the Windows convention ’\r\n’. All of these external representations are seen as ’\n’ by the Python program.{12 Chapter 2. Built-in Functions The Python Library Reference, Release 2.6}
2 rU 或 Ua 以读方式打开, 同时提供通用换行符支持(PEP 278).
3 ‘w'模式写入时文件不存在会自动创建,但目录不存在会报错:FileNotFoundError: [Errno 2] No such file or directory: './doc_word_mat/AlarmClock_doc_word_mat_file.txt'
if not exists('./doc_word_mat'):
makedir('./doc_word_mat')
doc_word_mat_file = open('./doc_word_mat/file.txt', 'w')
函数参数:编码encoding(打开文件的编码方式)
encoding is the name of the encoding used to decode or encode the file. This should only be used in text mode. The default encoding isplatform dependent, but any encoding supported by Python can bepassed.
默认方式与平台相关,如linux下可能默认是utf-8, windows下可能是gbk。
py3中open使用encoding打开文件后,字符串是unicode(可能是先使用encoding读取字符串,再decode成unicode了)。
带BOM的utf-8编码的txt文件时开头会有一个多余的字符\ufeff,BOM被解码为一个字符\ufeff,如何去掉?修改encoding为utf-8_sig或者utf_8_sig
函数参数:python文件读取路径
a.py: with open("***.txt", encoding='utf-8')as f
txt文件所在目录对应的是这个代码执行的目录(可能被另一个目录中的文件调用,则目录就是那个文件所在目录),而不是当前所在的文件a.py所在的目录。
所以这样打开文件有风险,可能***.txt和这行代码所在文件a.py在一个目录下,但是代码是在另一个目录(如b.py调用a.py中的函数)执行,这样就会出错:file not found error或者no file or directory named ***.txt
lz提供一个解决方案:
所有相对路径打开的文件改成这样的:
os.path.join(os.path.split(os.path.realpath(__file__))[0], filename)
这样就不会出错了,lz建议都这样写,因为在很多项目中py文件移来移去,虽然相对路径没变,但是py文件中的代码可以是被其它地方调用执行的,还是可能出错,lz遇到无数次了,所以如此建议
文件对象的方法
f.read(size) 返回最多size个字节的str,当size缺省或为负值时,整个文件内容都被作为一个str读出来,若到文末,返回空串' '
f.readline() 返回文件中一行的str,末尾加上换行符'\n'
list(f) or f.readlines() If you want to read all the lines of a file in a list
f.write(string) 将string写入file,返回成功写入的字符个数。
f.tell() returns an integer giving the file object’s current position in the filerepresented as number of bytes from the beginning of the file when in binary mode andan opaque number when in text mode. tell() 方法返回文件的当前位置,即文件指针当前位置。
f.close() 文件对象使用完一定要close()掉。
f.seek(offset, from_what) 改变文件对象的位置(position),offset为偏移量,from_what为参考位置,为0时从文件开头, 为1时使用当前的文件位置,为2是使用文件末尾位置。from_what默认为0
[Methods of File Objects¶]
使用示例
1 按行从文件中读取,有一种简便的方式
1 f = open("print.py", "r+")
2 for line in f: #line的结尾会自动有一个“\n"
3 print(line, end=" ") #所以end=' ', 默认会又输出换行符
2 把print.py中的内容读出来,写到一个新文件中,在打印出来。
f = open("print.py", "r")
f2 = open("wyfile", "w+") #使用w+文件不存在时候才会创建
for line in f:
f2.write(line)
f2.seek(0) #这行语句之前,f2的位置在文末,所以必须调整到文件开头。
print(f2.read(), end=' ')
f.close() #记住要释放
f2.colse()
[Reading and Writing Files¶]
python文件中的读入科学计数法的数字
float(num)
Python读取文件其它方法
方法2. 带缓存的文件读取
lines = file.readlines(100000)
for line in lines:
pass # do something
事实证明,用同样的数据测试,它每秒可以读96900行数据!效率是第一种方法的3倍!
方法3.linecache文件读取
lines = linecache.getlines(r'.\datasets\lastfm-dataset-1K\item_item_csr_mat.mtx')[2:-1]
for l in lines:
pass
读取速度是前两个的N倍--///
读取并表示成相同数据类型的时间比较
s = time.time()
lines = [line.split() for line in linecache.getlines(checkin_filename)]
e = time.time()
print(e - s)
lines = np.loadtxt(checkin_filename, dtype=bytes).astype(str)
s = time.time()
print(s - e)
lines = pd.read_csv(checkin_filename, sep='\t', header=None, parse_dates=[1])
e = time.time()
print(e - s)
11.72770071029663
168.77640986442566
130.63407826423645
方法4.Python with open file 用with语句打开文件
python中的with的作用是自动释放对象,即使对象在使用的过程中有异常抛出。可以使用with的类型必须实现__enter__ __exit__。我的理解是=try...finally{},在finally中调用了释放函数。
[类似与CSharp中的using(){}关键字,用来自动确保调用对象的dispose()方法,即使对象有异常抛出。C#中可以使用using{}的对象必须已经实现了IDispose接口。]
def TestWith():
with open("myfile.txt") as f:
for line in f:
print (line)
f.readline() #f is already clean up here, here will meet ValueError exception
Note:
1. with + try...except既能让对象自动释放,又包含了异常捕获的功能
2.The with statement is a useful when accessing anything that supports the context management protocol. Which meansopen()
for example. It basically makes sure that any set up and clean up code, such as closing files, is run without having to worry about it.
[python - 异常处理、with语句]
[浅谈 Python 的 with 语句]
[python with as语法]
[模块contextlib,使你不用构造含有__enter__, __exit__的类就可以使用with]
方法5. python以batch的方式读取文件,一次读取n行
for next_n_lines in zip_longest(*[file] * batch_size, fillvalue=None)
即先生成一个batch_size大小内容全为同一个文件的list,再解构,生成一个tuple,list中的文件其实是按照顺序zip的,每次zip file都会移动batch_size行,不足的行用None替代。
Note: 注意batch处理时,fillvalue值可以选择不处理,直接抛弃。
[How to chunk a list in Python 3?]
Python文件关闭机制
1. 最简单的就是我们可以通过调用f.close()显式地关闭文件。一旦我们关闭了文件,该文件对象依然存在,但是我们无法再通过它来读取文件内容了,而且文件对象返回的可打印内容也表明文件已经被关闭。
2. 打开文件的优选最佳实践方式是使用前面的 “with” 语句。在 “with” 打开的代码块内,文件是打开的,而且可以自由读取。然而,一旦Python代码从 “with” 负责的代码段退出,文件会自动关闭。所以,通过使用 “with”,你避免了显式地关闭文件的操作。Python 会以一种不那么有 Python 风格的方式在幕后神奇而静静地替你关闭文件。
但是你不显式地关闭文件会怎样?如果你有点懒,既不使用 “with” 代码块也不调用f.close()怎么办?这时文件会什么时候关闭?
我总是假定当对象的引用计数降为0时,Python会关闭文件,进而垃圾回收机制清理文件对象。当我们读文件时很难证明或核实这一点,但写入文件时却很容易。这是因为当写入文件时,内容并不会立即刷新到磁盘(除非你向“open”方法的第三个可选参数传入“False”),只有当文件关闭时才会刷新。
f = open('/tmp/output', 'w')
f.write('abcn')
f.write('defn')
# check contents of /tmp/output (1)
del(f)
# check contents of /tmp/output (2)
# exit from Python
# check contents of /tmp/output (3)
实验表明:
1. Python 2.7,报告显示在阶段一文件存在但是是空的,阶段二和阶段三中文件包含所有的内容。这样,在CPython 2.7中我最初的直觉似乎是正确的:当一个文件对象被垃圾回收时,它的 __del__ (或者等价的)方法会刷新并关闭文件。而且在我的IPython进程中调用“lsof”命令显示文件确实在引用对象移除后被关闭了。
2. Python3 ,得到了相同的结果。移除对文件对象最后的引用后会导致文件被刷新并且被关闭。
3. PyPy 和 Jython下,得到了不同的结果!删除文件对象的引用后——也就是在阶段2,并没有导致文件内容被刷入磁盘。我不得不假设这和垃圾回收机制的不同或其他在 PyPy 和 CPython中工作机制的不同有关系。但是如果你在 PyPy中运行程序,就绝不要指望仅仅因为文件对象的引用结束,文件就会被刷新和关闭。命令 lsof 显示直到Python进程退出时文件才会被释放。也就是说,从 Python 退出确实会确保缓存中的数据写入磁盘。
4.在 Python 2.7 的环境下,“abcn” * 1000 语句执行后没有任何东西写入。但“defn” * 1000 语句执行后,文件包含有4096个字节——可能代表缓冲区的大小。调用 del(f) 删除文件对象的引用导致数据被刷入磁盘和文件关闭,此时文件中共有8000字节的数据。所以忽略字符串大小的话 Python 2.7 的行为表现基本相同。唯一不同的是如果超出了缓冲区的大小,那么一些数据将在最后文件关闭数据刷新前写入磁盘。
换做是Python 3的话,情况就有些不同了。f.write执行后没有任何数据会写入。但是文件对象引用一旦结束,文件就会刷新并关闭。这可能是缓冲区很大的缘故。但毫无疑问,删除文件对象引用会使文件刷新并关闭。
5. 至于 PyPy 和 Jython,对大文件和小文件的操作结果都一样:文件在 PyPy 或 Jython 进程结束的时候刷新并关闭,而不是在文件对象的引用结束的时候。
Note:然而如果使用 “with” 进行了实验。在所有情况下,我们都能够轻松的预测文件是何时被刷新和关闭的——就是当退出代码段,并且上下文管理器在后台调用合适方法的时候。
如果你不使用“with”,那么至少在非常简单的情形下,你的数据不一定有丢失的危险。然而你还是不能确定数据到底是在文件对象引用结束还是程序退出的时候被保存的。如果你假定因为对文件唯一的引用是一个本地变量所以文件在函数返回时会关闭,那么事实一定会让你感到吃惊。如果你有多个进程或线程同时对一个文件进行写操作,那么你真的要非常小心了。
[Python文件关闭机制详解]
python文件读取技巧
计算文件的行数
最简单的办法是把文件读入一个大的列表中,然后统计列表的长度.如果文件的路径是以参数的形式filepath传递的,那么只用一行代码就可以完成我们的需求了:
count = len(open(filepath,'rU').readlines())
如果是非常大的文件,上面的方法可能很慢,甚至失效.此时,可以使用循环来处理:
count = -1
for count, line in enumerate(open(thefilepath, 'rU')):
pass
count += 1
另外一种处理大文件比较快的方法是统计文件中换行符的个数'\n '(或者包含'\n'的字串,如在windows系统中):
count = 0
thefile = open(thefilepath, 'rb') #参数'rb'是必须的,否则在windows系统上,上面的代码会非常慢.
while True:
buffer = thefile.read(8192*1024)
if not buffer:
break
count += buffer.count('\n')
thefile.close( )
python对目录下的文件排序
[http://1.guotie.sinaapp.com/?p=26]
python读入文件到矩阵中
1. numpy读取
[numpy教程:基本输入输出和文件输入输出Input and output ]
2.pandas读取
from:Python文件输入输出_np.load dtype-CSDN博客
ref: [Reading and Writing Files¶]
[python文件和目录访问File and Directory Access]***
Python格式化输出到文件
python读写word、csv、json文件
python文件、目录及路径操作
python模块 - pickle模块
使用 Python 读取 8 GB 大小的文件