Python 文件 I/O(学习总结)

浏览: 752

打开和关闭文件

open 函数

你必须先用Python内置的open()函数打开一个文件,创建一个file对象,相关的方法才可以调用它进行读写。
语法:

file object = open(file_name [, access_mode][, buffering])

各个参数的细节如下:

  • file_name:file_name变量是一个包含了你要访问的文件名称的字符串值。
  • access_mode:access_mode决定了打开文件的模式:只读,写入,追加等。这个参数是非强制的,默认文件访问模式为只读(r)。

所有可取值如下:

r: 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb: 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式
r+: 打开一个文件用于读写。文件指针将会放在文件的开头。
rb+:以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
w:打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
wb:以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件
w+:打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
wb+:以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件
a:打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab:以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+:打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+:以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

  • buffering:如果buffering的值被设置为0,就不会被寄存。如果buffering的值取1,访问文件时会被寄存。如果将buffering的值设置为大于1的整数,表明了这就是寄存区的缓冲大小。如果取负值,寄存区的缓冲大小则为系统默认。

file对象的属性

直接用实例来说明:

fo=open("foo.txt","wb")#打开一个文件
print"文件名:",fo.name  # file.name 返回文件的名称
print"是否关闭:",fo.closed  #file.closed如果文件关闭返回ture,否则返回false.
print"访问模式:",fo.mode  #file.mode返回被打开文件的访问模式。
print"末尾是否强制加空格:",fo.softspace  #file.softspace 如果用print输出后,必须跟一个空格符,则返回False。否则返回Ture。
输出结果为:
文件名:foo.txt
是否关闭:False
访问模式:wb
末尾是否强制加空格:0

file对象方法

  • close()方法

file 对象的 close()方法刷新缓冲区里任何还没写入的信息,并关闭该文件,这之后便不能再进行写入。
当一个文件对象的引用被重新指定给另一个文件时,Python 会关闭之前的文件。用 close()方法关闭文件是一个很好的习惯。
语法:

fileobject.close();

列子:

#打开一个文件
fo=open("fo.txt","wb")
print "文件名",fo.name
#关闭打开的文件
fo.close()
输出结果为:
文件名:foo.txt
  • write()方法

write()方法可将任何字符串写入一个打开的文件。需要重点注意的是,Python字符串可以是二进制数据,而不是仅仅是文字。
write()方法不会在字符串的结尾添加换行符('\n'):

语法:

fileobject:write(string);

在这里,被传递的参数是要写入到已打开文件的内容。

例子:

# 打开一个文件
fo = open("foo.txt""wb")
fo.write( "hello,world\I love Python\n");

# 关闭打开的文件
fo.close()

打开文件,会看到下面的结果:
hello world
I love Python
  • read()方法

read()方法从一个打开的文件中读取一个字符串。需要重点注意的是,Python字符串可以是二进制数据,而不是仅仅是文字。

语法:

fileObject.read([count]);

在这里,被传递的参数是要从已打开文件中读取的字节计数。该方法从文件的开头开始读入,如果没有传入count,它会尝试尽可能多地读取更多的内容,很可能是直到文件的末尾。

例子:

#打开一个文件
fo.open("foo.txt","r+"#还是用以上我们创建的foo.txt文件
str=fo.read(10);
print "读取的字符串是:",str
#关闭打开的文件
fo.close()

输出结果:

读取的字符是:hello,worl
  • tell()方法:文件定位

tell()方法告诉你文件内的当前位置;换句话说,下一次的读写会发生在文件开头这么多字节之后。

  • seek() 方法

seek(offset [,from])方法改变当前文件的位置。offset变量表示要移动的字节数。from变量指定开始移动字节的参考位置。
如果from被设为0,这意味着将文件的开头作为移动字节的参考位置。如果设为1,则使用当前的位置作为参考位置。如果它被设为2,那么该文件的末尾将作为参考位置。

例子:

  #还是用上面创建的文件foo.txt
fo=open("foo.txt",r+)
str=fo.read(11)
print"读取的字符串是:",str

#查找当前的位置

position=fo.tell()
print"当前文件位置:",position

#把指针再次重新定位到文件开头

position=fo.seek(0,0);
str=fo.read(11)
print"重新读取字符串:",str
#关闭打开的文件
fo.close()

输出的结果:
读取的字符串是:hello,world
当前的位置:11
重新读取字符串:hello,world

延伸

我们最后的一步是调用close()方法关闭文件。文件用完之后必须要关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的。

由于文件读写时都有可能产生IOErro,一旦出错,后面的f.close(),就不会调用。所以,为了保证无论是否出错都能正确的关闭文件,我们可以使用try….finally;来实现:

try:
    f=open('/path/to/file','r')
    print (f.read())
finally:
    if f:
        f.close()

但是每次都这样写比较繁琐的,所以Python 引入了with语句来自动帮我们调用close()方法:

with open('path/to/file','r'as f:
    print (f.read())

这和前面的try … finally是一样的,但是代码更佳简洁,并且f.close()方法
已经自动调过了。

  • with 是如何工作的呢

上例中”open()”方法是Python自带的,那我们怎么定义自己的类型来使用with语句呢。基本思想是with所求值得对象必须有一个enter__()方法,一个_exit()_方法。紧跟with后面的语句被求值后,返回对象的_enter_()方法被调用,这个方法的返回值被赋值给as后面的变量。当with后面的代码被全部执行完之后,将调用返回对象的__exit()方法。

class Sample:
    def __enter__(self):
        print("In __enter__()")
        return "Foo"

    def __exit__(self, type, value, trace):
        print("In __exit__()")


def get_sample():
    return Sample()

with get_sample() as sample:
    print( "sample:", sample)

输出结果

In __enter__()
sample: Foo
In __exit__()

观察输出结果:

  1. enter()方法被执行
  2. enter()方法返回的值 - 这个例子中是"Foo",赋值给变量'sample'
  3. 执行代码块,打印变量"sample"的值为 "Foo"
  4. exit__()方法被调用with真正强大之处是它可以处理异常。可能你已经注意到Sample类的__exit方法有三个参数- val, type 和 trace。 这些参数在异常处理中相当有用。我们来改一下代码,看看具体如何工作的。
    class Sample:
        def __enter__(self):
           return self

        def __exit__(self, type, value, trace):
            print("type:", type)
            print("value", value)
            print("trace", trace)

        def do_something(self):
            bar = 1 / 0
            return bar + 10

    def get_sample():
        return Sample()

    with Sample() as sample:
        sample.do_something()
    输出结果:

    Traceback (most recent call last):
    type: <class 'ZeroDivisionError'>
      File "C:/Users/lkx941013/PycharmProjects/lianxi11/5.py", line 21in <module>
    value division by zero
    trace <traceback object at 0x000000D6A2A9AD88>
        sample.do_something()
      File "C:/Users/lkx941013/PycharmProjects/lianxi11/5.py", line 12in do_something
        bar = 1 / 0
    ZeroDivisionError: division by zero

    Process finished with exit code 1

这个例子中,with后面的get_sample()变成了Sample()。这没有任何关系,只要紧跟with后面的语句所返回的对象有enter__()和_exit_()方法即可。此例中,Sample()的__enter()方法返回新创建的Sample对象,并赋值给变量sample。
观察执行结果

实际上,在with后面的代码块抛出任何异常时,exit__()方法被执行。正如例子所示,异常抛出时,与之关联的type,value和stack trace传给_exit_()方法,因此抛出的ZeroDivisionError异常被打印出来了。开发库时,清理资源,关闭文件等等操作,都可以放在__exit方法当中。
因此,Python的with语句是提供一个有效的机制,让代码更简练,同时在异常产生时,清理工作更简单

重命名和删除文件

Python的os模块提供了帮你执行文件处理操作的方法,比如重命名和删除文件。
要使用这个模块,你必须先导入它,然后才可以调用相关的各种功能。

  • rename()方法:

rename()方法需要两个参数,当前的文件名和新文件名。
语法:

os.rename(current_file_name, new_file_name)

例子:

下面将重命名的一个已经存在的文件test.txt

import os

# 重命名文件test1.txttest2.txt
os.rename( "test1.txt", "test2.txt" )
  • remove()方法

你可以用remove()方法删除文件,需要提供要删除的文件名作为参数

语法:

os.remove(file_name)

例子:
下例将删除一个已经存在的文件test2.txt。

import os

# 删除一个已经存在的文件test2.txt
os.remove("test2.txt")

操作文件和目录

操作文件和目录的函数一部分放在os模块中,一部分放在os.path模块中,这一点要注意一下。查看、创建和删除目录可以这么调用

  • mkdir()方法

可以使用os模块的mkdir()方法在当前目录下创建新的目录们也可以直接创建一单级目录(见例3)。你需要提供一个包含了要创建的目录名称的参数。
语法:

os.mkdir("newdir")

例子:
下例将在当前目录下创建一个新目录test。

import os

# 创建目录test
os.mkdir("test")
  • chdir()方法

可以用chdir()方法来改变当前的目录。chdir()方法需要的一个参数是你想设成当前目录的目录名称。
语法:

os.chdir("newdir")

例子:
下例将进入"/home/newdir"目录

import os

# 将当前目录改为"/home/newdir"
os.chdir("/home/newdir")
  • getcwd()方法:

getcwd()方法显示当前的工作目录。
语法:

   os.getcwd()

例子:
下例给出当前目录:

 import os
 # 给出当前的目录
 print os.getcwd()
  • rmdir()方法

rmdir()方法删除目录,目录名称以参数传递。在删除这个目录之前,它的所有内容应该先被清除。
语法:

   os.rmdir('dirname')

例子:
以下是删除" /tmp/test"目录的例子。目录的完全合规的名称必须被给出,否则会在当前目录下搜索该目录。

import os
# 删除”/tmp/test”目录
os.rmdir( "/tmp/test"  )
  • os.path.join() 方法

把两个路径合成一个时,不要直接拼字符串,而要通过os.path.join()函数,这样可以正确处理不同操作系统的路径分隔符。在Linux/Unix/Mac下,os.path.join()返回这样的字符串:

part-1/part-2

而Windows下会返回这样的字符串:

part-1\part-2
  • os.path.split()

同样的道理,要拆分路径时,也不要直接去拆字符串,而要通过os.path.split()函数,这样可以把一个路径拆分为两部分,后一部分总是最后级别的目录或文件名:

>>> os.path.split('/Users/michael/testdir/file.txt')
('/Users/michael/testdir''file.txt')
  • os.path.splitext()

os.path.splitext()可以直接让你得到文件扩展名,很多时候非常方便:

  >>> os.path.splitext('/path/to/file.txt')
 ('/path/to/file''.txt')

这些合并、拆分路径的函数并不要求目录和文件要真实存在,它们只对字符串进行操作。
但是复制文件的函数居然在os模块中不存在!原因是复制文件并非由操作系统提供的系统调用。
幸运的是shutil模块提供了copyfile()的函数,你还可以在shutil模块中找到很多实用函数,它们可以看做是os模块的补充。

通过实例掌握知识点

  • 列1:创建文件并写入内容
    import os 
    import os.path   #os.path 此模块用来操作路径
    ls = os.linesep  #os.linesep字符串给出当前平台使用的行终止符。例如,Windows使用'\r\n',Linux使用'\n'而Mac使用'\r'

    #获得文件名
    filename = input('Enter a file name:')
    while True:

        if os.path.exists(filename): #os.path.exists()是判断文件路径是否存在
            print("ERROR: '%s' already exists" % filename)
        else:
            break

    all = []
    print("\nEnter lines ('.' by iteself to quit).\n")   #'\n' 是换行的意思

    #循环直到用户输入'.'终止,把内容先写入一个数列中
    while True:     
        entry = input('>')
        if entry == '.':
            break
        else:
            all.append(entry)

    fobj = open(filename, 'w') # 打开文件
    fobj.writelines(['%s%s' %(x, ls) for x in all])  #把数列中的内容一行一行的放入文件里
    fobj.close()  #关闭文件
    print("Done!")

    输出结果:
    Enter a file name:1043

    Enter lines ('.' by iteself to quit).

    >1043
    >study
    >group
    >.
    Done!

下面我们找到这个文件来看看

想知道在哪里找到吗?看例2想知道在哪里找到吗?看例2

  • 例2:打开上面的1043文件
    filename = '1043'
    try:
        fobj = open(filename, 'r')#以读的方式打开文件
    except IOError as e:
        print("*** file open error", e)
    else:
        for eachLine in fobj:
            print(eachLine.strip())#strip() 1.语法:str.strip([chars]); 2.返回值是返回移除字符串头尾指定的字符生成的新字符串。3.strip()默认删除空白符
        fobj.close()

    输出结果:
    1043

    study

    group

  • 例3:创建目录


    <br />import os<br />a=os.getcwd()#获取当前路径<br />print(a)<br />b=os.listdir(os.getcwd())#获取当前目录中的内容<br />print(b)<br />os.mkdir('D:\hel')#只创建单层目录<br />os.makedirs('D:\helos\he')#创建多级目录</p><p>输出结果:<br />C:\Users\hk\PycharmProjects\lianxi11 #这是输出的a<br />['.idea', '1.py', '1043', '2.py', '3.py', '4.py', 'a.py', 'b.py', 'c.py', 'd.py', 'hhr', 'kkuu', 'lkgg', 'studypython'] #这是b</p></li></ul>

    查看在自己的D盘中确实有hel文件夹,helos文件夹,并且helos文件夹中有一个he

    完!

推荐 0
本文由 DataFrog 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册