快捷搜索:
来自 计算机编程 2019-08-03 17:47 的文章
当前位置: 67677新澳门手机版 > 计算机编程 > 正文

文件和异常

一、从文件中读取数据

    至此,我们掌握了编写组织有序而易于使用的程序所需的基本技能,该考虑让程序目标更明确,用途更大了。在本章中,我们将学习处理文件,让程序能够快速地分析大量的数据;我们将学习错误处理,避免程序在面对意外情形时崩溃;我们将学习异常,它们是Python创建的特殊对象,用于管理程序运行时出现的错误;我们还将学习模块json,它让我们能够保存用户数据,以免在程序停止运行后丢失。

1.读取整个文件

1 with open('pi_digits.txt')as file_object:
2     contents = file_object.read()
3     print(contents)

 (当前目录下已有pi_digits.txt)

函数 open() 接受一个参数,文件名称,然后在当前执行的文件所在的目录中查找指定的文件,最后返回一个文件对象。

关键字 with 在不需要访问文件后将其关闭。(也可以使用open,close,但是如果程序中断没有close则会出问题,文件不关闭可能导致数据丢失或者受损)

有了文件对象之后,可以用 read() 方法读取文件的全部内容,并将其作为一个长长的字符串存储在contents中

(read()读到文件末尾时返回一个空字符串,而将这个空字符串显示出来时是一个空行,所以上面程序执行完最后会多出一个空行,可用rstrip()删除末尾的空行 print(contents.rstrip()))

    学习处理文件和保存数据可以让我们的程序使用起来更容易:用户将能够选择输入什么样的数据,以及在什么时候输入;用户使用我们的程序做一些工作后,可将程序关闭,以后在接着往下做。学习处理异常可帮助我们应对文件不存在的情形,以及处理其他可能导致程序崩溃的问题。这让我们的程序在面对错误的数据时更健壮——不管这些错误数据源自无意的错误,还是源自破坏程度的恶意企图。我们在本章学习的技能可提高程序的适用性、可用性和稳定性。

2.文件路径

如果文件不在当前目录下,则需要提供文件路径。

相对文件路径:文件在当前文件夹的子文件夹中。比如在当前目录的test文件夹下:

在Linux和OS X 中,可以这样写: 1 with open('test/pi_digits.txt')as file_object: 

在Windows中,可以这样写: 1 with open('testpi_digits.txt')as file_object: 

绝对文件路径:文件在计算机中的准确位置。一般路径较长,存储在一个变量中;

在Linux和OS X 中,可以这样写:

1 file_path = '/home/ehmatthes/other_files/text_files/filename.txt'
2 with open(file_path) as file_object:

 在Windows中,可以这样写:

1 file_path = 'C:Usersehmatthesother_filestext_filesfilename.txt'
2 with open(file_path) as file_object:

10.1    从文件中读取数据

3.逐行读取

可使用for循环 

1 filename = 'pi_digits.txt'
2 
3 with open(filename)as file_object:
4     for line in file_object:
5         print(line)

第1行将文件名存在变量中是一种常见的做法。

    文本文件可存储的数据量多的难以置信:天气数据、交通数据、社会经济数据、文学作品等。每当需要分析或修改存储在文件中的信息时,读取文件都很有用,对数据分析应用程序来说尤其如此。例如,我们可以编写一个这样的程序:读取一个文本文件的内容,重新设置这些数据的格式并将其写入文件,让浏览器能够显示这些内容。

4.创建一个包含文件各行内容的列表

1 filename = 'pi_digits.txt'
2 
3 with open(filename)as file_object:
4     lines = file_object.readlines()
5 
6 for line in lines:
7     print(line.rstrip())

4️⃣处的 readlines() 方法从文件中读取每一行,并将其存储在一个列表中

    要使用文本文件中的信息,首先需要将信息读取到内存中。为此,我们可以一次性读取文件的全部内容,也可以以每次一行的方式逐步读取。

5.使用文件的内容

 1 filename = 'pi_digits.txt'
 2 
 3 with open(filename)as file_object:
 4     lines = file_object.readlines()
 5 
 6 pi_string = ''
 7 for line in lines:
 8     pi_string  = line.strip()
 9 
10 print(pi_string)
11 print(len(pi_string))

读取文本文件时,Python 将其中的所有文本都解读为字符串,若要使用数值,则用int(),float()转换

10.1.1  读取整个文件

6.包含一百万位的大型文件

Python没有任何限制,只要内存足够大,下面的程序如果不加限制,有的机器可能受不了

 1 filename = 'pi_million_digits.txt'
 2 
 3 with open(filename)as file_object:
 4     lines = file_object.readlines()
 5 
 6 pi_string = ''
 7 for line in lines:
 8     pi_string  = line.strip()
 9 
10 print(pi_string[:50] '...')
11 print(len(pi_string))
12 # 结果是
13 # 3.141592653589793238462643383279502884197169399375...
14 # 1000002

    要读取文件,需要一个包含几行文本的文件。下面首先来创建一个文件,它包含精确到小数点后30位的圆周率值,且在小数点后每10处换行:

二、写入文件

保存数据的最简单的方式之一是将其写入到文件中

  pi_digits.txt

1.写入空文件

1 filename = 'a.txt'
2 
3 with open(filename, 'w')as file_object:
4     file_object.write('I love you. ')

        open() 中有两个实参,一个是文件名称,一个是 'w',这告诉Python以写入模式打开这个文件,打开文件时,可以指定读取模式( 'r' ),写入模式( 'w' ),附加模式( 'a' ),读取和写入模式( 'r ' ),省略模式实参则是只读模式。

如果要写入的文件不存在,open() 将会自动创建它;如果已经存在,则会覆盖之前的内容,这点要注意。

Python只能将字符串写入文本文件,若要存储数值,则应该使用str()将其转换后写入。

  3.1415926535

2.写入多行

函数 write() 不会在末尾添加换行符,所以要这样写: 1 file_object.write('I love you.n') 2 file_object.write('I love you too.') 

  8979323846

3.附加到文件

使用附加模式,写入的行都会添加至文件末尾,如果文件不存在会创建新文件。

 1 with open(filename, 'a') as file_object: 2 file_object.write('nFuck you! ') 

  2643383279

三、异常

Python使用被称为异常的特殊对象来管理程序执行期间发生的错误。

每当发生错误时,Python都会创建一个异常对象,如果你编写了处理该异常的代码,程序将继续运行,否则程序将停止。

异常是使用 try-except 代码块 处理的,使用该代码块时,即便出现异常,程序会显示你编写的信息,然后继续运行。

    下面的程序打开并读取这个文件,再将其内容显示到屏幕上:

1.处理 ZeroDivisionError 异常

下面创建一个除法计算器:

 1 print("Give me two numbers, and I'll divide them. ")
 2 print("Enter 'q' to quit. ")
 3 
 4 while True:
 5     first_number = input("nFirst number: ")
 6     if first_number == 'q':
 7         break
 8     second_number = input("Second number: ")
 9     if second_number == 'q':
10         break
11     try:
12         answer = int(first_number)/int(second_number)
13     except ZeroDivisionError:
14         print("You can't divide by 0 ! ")
15     else:
16         print(answer)

 第11-16行为 try-except-else 代码块,将能引发异常的代码放在try语句中,try代码成功运行时运行else

    file_reader.py

2.失败时一声不吭

Python有一个 pass 语句,可在代码块中使用它来让 Python 什么都不要做

1     try:
2         answer = int(first_number)/int(second_number)
3     except ZeroDivisionError:
4         pass
5     else:
6         print(answer)

    with open('pi_digits') as file_object:

四、使用模块json来存储数据

JSON(JavaScript Object Notation) 格式最初是为 JavaScript 开发的,后来成为了一种常见的格式。

模块 json 让你能够将简单的Python数据结构转储到文件中,并在程序再次运行时加载该文件中的数据。

        contents = file_object.read()

1.使用 json.dump() 和 json.load()

先编写一个存储一组数字的简短程序;

1 import json
2 
3 numbers = [2, 3, 4, 5, 6, 7, 9]
4 
5 filename = 'num.json'
6 with open(filename, 'w') as f_obj:
7     json.dump(numbers, f_obj)

 在编写一个将这些数字读取到内存中的程序:

1 import json
2 
3 filename = 'num.json'
4 with open(filename) as f_obj:
5     numbers = json.load(f_obj)
6 
7 print(numbers)

 这是一种在程序之间共享数据的简单方式

重构:将代码划分为一系列完成具体工作的函数

    print(contents)

    在这个程序中,第1行代码做了大量的工作。我们先来看看函数open()。要以任何方式使用文件——哪怕仅仅是打印其内容,都得先打开文件,这样才能

访问它。函数open()接受一个参数:要打开的文件的名称。Python在当前执行的文件所在的目录中查找指定的文件。在这个示例中,当前运行的是file_reader.py,因此Python在file_reader.py所在的目录中查找pi_digits.txt。函数open()返回一个表示文件的对象.在这里,open('pi_digits.txt')

返回一个表示文件pi_digits.txt的对象;Python将这个对象存储在我们将在后面使用的变量中。

    关键字with在不再需要访问文件后将其关闭。在这个程序中,注意我们调用了open(),但没有调用close();我们也可以调用open()和close()来打开和关闭文件,但这样做时,如果程序存在bug,导致close()语句未执行,文件将不会关闭。这看似微不足道,但未妥善地关闭文件可能会导致数据丢失或受损。如果在程序中过早地调用close(),我们会发现需要使用文件时它已关闭(无法访问),这会导致更多的错误。并非在任何情况下都能轻松确定关闭文件的恰当时机,但通过使用前面所示的结构,可让Python去确定:我们只管打开文件,并在需要时使用它,Python自会在合适的时候自动将其关闭。

    有了表示pi_digits的文件对象后,我们使用方法read()读取这个文件的全部内容,并将其作为一个长长的字符串存储在变量contents中。这样,通过打印

contents的值,就可将这个文本文件的全部内容显示出来。

  3.1415926535
    8979323846
    2643383279

    为何会多出这个空行呢?因为read()到达文件末尾时返回一个空字符串,而将这个空字符串显示出来时就是一个空行。要删除末尾的空行,可在print语句中使用rstrip()

    with open('pi.digits') as file_object:

    contents = file_object.read()

    print(contents.rstrip())

    本书前面说过,Python方法rstrip()删除(剥除)字符串末尾的空白。现在,输出与原始文件的内容完全相同:

  3.1415926535
    8979323846
    2643383279

10.1.2  文件路径

    当我们将类似pi_digits.txt这样的简单文件名传递给open()时,Python将在当前执行的文件(即.py程序文件)所在的目录中查找文件。

    根据我们组织文件的方式,有时可能要打开不在程序文件所属目录中的文件.例如,我们可能将程序文件存储在了文件夹python_work中,而在Python_work中,有一个名为text_files的文件夹,用于存储文件操作的文本文件。虽然文件夹text_files包含在文件Python_work中,但仅向open()传递位于该文件夹中的文件的名称也不可行,因为Python只在文件夹Python_work中查找,而不会在其子文件夹text_files中查找。要让Python打开不与程序文件在同一个目录中

的文件,需要提供文件路径,它让Python到系统的特定位置去查找。

    由于文件夹text_files位于文件夹python_work中,因此可使用相对文件路径来打开该文件夹中的文件。相对文件路径让Python到指定的位置去查找,而该位置是相对于当前运行程序所在目录的。在Linux和OS X中,我们可以这样编写代码:

    with open('text_files/filename.txt') as file_object:

    我们还可以将文件在计算机中的准确位置告诉Python,这样就不用关心当前运行的程序存储在什么地方了。这称为绝对文件路径。在相对文件行不通时,可使用绝对路径。例如,如果text_files并不在文件夹Python_work中,而在文件夹other_files中,则向open()传递路径'text_files/filename.txt'行不通,因为Python只在文件夹Python_work中查找该位置。为明确地指出我们希望Python到哪里去查找,我们需要提供完整的路径。

    绝对路径通常比相对路径更长,因此将其存储在一个变量中,因此将其存储在一个变量中,再将该变量传递给open()会有所帮助。在Linux和OS X中,绝对路径类似于下面这样:

    file_path = '/home/ehmattes/other_files/text_files/filename.txt'

    with open(file_path) as file_object:

    通过使用绝对路径,可读取系统任何地方的文件。就目前而言,最简单的做法是,要么将数据文件存储在程序文件所在的目录,要么将其存储在程序文件所在目录下的一个文件夹(如text_files)中。

注意: Windows系统有时候能够正确地解读文件路径中的斜杠。如果你使用的是Windows系统,且结果不符合预期,请确保在文件路径中使用的是反斜杠。另外,由于反斜杠在Python中被视为转义标记,为在Windows中确保万无一失,应以原始字符串的方式指定路径,即在开头的单引号前加上r.

    绝对路径:

    file_path = '/home/zhuzhu/title10/pi_digits'
  with open(file_path) as file_object:
    cotents = file_object.read()
    print(cotents.rstrip())

10.1.3  逐行读取

    读取文件时,常常需要检查其中的每一行:我们可能要在文件中查找特定的信息,或者要以某种方式修改文件中的文本。例如,我们可能要遍历一个包含天气数据的文件,并使用天气描述中包含字样sunny的行。在新闻报道中,我们可能会查找包含标签<headline>的行,并按特定的格式设置它。

    要以每次一行的方式检查文件,可对文件对象使用for循环:

file_reader.py

filename = 'pi_digits'                                  --(1)

with open(filename) as file_object:                     --(2)

  for line in file_object:                            --(3)

    print(line)

    在(1)处,我们将要读取的文件的名称存储在变量filename中,这是使用文件时一种常见的做法。由于变量filename表示的并非实际文件——它只是一个让Python知道到哪里去查找文件的字符串,因此可轻松地将'pi_digits'替换为你要使用的另一个文件的名称。调用open()后,将一个表示文件及其内容的对象存储到了变量file_object中。这里也使用了关键字with,让Python负责妥善地打开和关闭文件。为查看文件的内容,我们通过对文件对象执行循环来遍历文件中的每一行。

    我们打印每一行,发现空白行更多了:

3.1415926535

  8979323846

  2643383279
    为何会出现这些空白行呢?因为在这个文件中,每行的末尾都有一个看不见的换行符,而print语句也会加上一个换行符,因此每行末尾都

本文由67677新澳门手机版发布于计算机编程,转载请注明出处:文件和异常

关键词: