python基础8-文件和异常

8.1、从文件中读取数据

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

8.1.1、读取整个文件

要以任何方式使用文件,都要先打开文,这样才能访问。

open()接受一个参数,表示要打开文件的文件名

with在不再需要访问文件后将其关闭

在这个例子中,没有使用close()来关闭文件,但是可以调用open()和close()来打开和关闭文件,但是如果这样做的话,如果程序存在bug,导致close()语句未执行,文件将不会关闭,未妥善关闭文件会导致数据丢失或受损。

通过这种结构,可以让Python去决定什么时候讲文件关闭

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

输出结果会多一个空行,因为read()到达文件末尾时返回一个空字符串,而将这个空字符串显示出来时就是一个空行,可以在print语句中使用rstrip()来消除空行

8.1.2、文件路径

python只会在文件夹中找,而不会在其子文件夹中查找,因此要让python打开不与程序文件位于同一个目录中的文件,需要提供文件路径。

  • linux中使用斜杠/
  • windows中使用反斜杠\

8.1.3、逐行读取

读取文件是,常常需要检查其中的每一行:你可能要在文件中查找特定的信息,或者要以某种方式修改文件中的文本。

每行的末尾都有一个看不见的换行符,而print语句也会加上一个换行符,因此每行末尾都有两个换行符,可在Print语句中使用rstrip()函数来消除换行符

filename = 'pi_digits.txt'

with open(filename) as file_object:
    for line in file_object:
        print(line)

8.1.4、创建一个包含文件各行内容的列表

使用关键字with是,open()返回的文件对象只能在with代码块中使用。如果要在with代码外访问文件的内容,可在with代码块内将文件的各行存储在一个列表中,并在with代码块外使用该列表

ef read_file_on_line(filename):
    with open(filename) as file_object:
        lines = file_object.readlines()

    for line in lines:
        print(line.rstrip())


filename = 'pi_digits.txt'
read_file_on_line(filename)

8.1.5、使用文件的内容

将文件读取到内存中后,就可以以任何方式使用这些数据了。

python将文本内容都解读为字符串,如果读取的是数字,需要使用int()或者float()函数将其转换为浮点数

filename = 'pi_digits.txt'

with open(filename) as file_object:
    lines = file_object.readlines()

pi_string = ""
for line in lines:
    pi_string += line.rstrip()

print(pi_string)
print(len(pi_string))

8.1.6、包含一百万位的大型文件

在文件中有大量数据时,可以使用列表截取的方式来读取随机位置的有限位文本

filename = 'pi_digits.txt'

with open(filename) as file_object:
    lines = file_object.readlines()

pi_string = ""
for line in lines:
    pi_string += line.rstrip()

print(pi_string[:52] + "...")
print(len(pi_string))

8.2、写入文件

8.2.1、写入空文件

需要将文本写入文件,在调用open()时需要提供另一个实参,表示要往打开的文件中写入文本数据。

在这个实例中,调用open()时,提供了两个实参,第一个是打开文件的名称,第二个实参表示要以写入模式打开这个文件。

打开文件有以下几种模式:

  • 读取模式 'r' (默认只读取)
  • 写入模式 'w'
  • 附加模式 'a'
  • 读取和写入文件 'r+'
filename = 'programming.txt'

with open(filename, 'w') as file_object:
    file_object.write("I love programming.")

8.2.2、写入多行

函数write不会在写入的文本末尾添加换行符,所以如果需要写入多行的话,注意使用'\n'换行符来换行

像显示到终端的输出一样,还可以使用空格,制表符和空行来设置这些输出的格式

def write_file(filename, str):
    # write back to file

    with open(filename, 'w') as file_object:
        file_object.write(str)


str = 'I love programming.\n'
str += 'I love creating new games.\n'
write_file('programming.txt', str)

8.2.3、在文件中追加内容

如果要在文件末尾添加内容,而非覆盖原有的内容,可以使用附加模式打开文件,这种模式下,python不会在返回文件对象前清空文件,而将新写入的内容都追加到文件末尾。

def write_file(filename, str):
    # write back to file

    with open(filename, 'a') as file_object:
        file_object.write(str)


str = 'I love programming.\n'
str += 'I love creating new games.\n'
write_file('programming.txt', str)

8.3、异常

python使用异常的特殊对象来管理程序执行期间发生的错误,当出现错误时,python会创建一个异常对象。如果在程序中对异常对象进行处理,则程序会继续运行,否在程序将停止,并显示一个traceback,其中包含有关异常的报告。

异常是使用try-except代码块处理的。

8.3.1、处理ZeroDivisionErro异常

除法运算,除数如果是0,就会报该错误

try:
  print(5/0)
expect ZeroDivisionError:
  print("You can`t divide by zero!")

8.3.2、使用异常避免崩溃

print("Give me two numbers, and I`ll divide them.")
print("Enter 'q' to quit.")

while True:
    first_number = input("\nFirst number:\n")
    if first_number == 'q':
        break

    second_number = input("\nSecond number:\n")
    if second_number == 'q':
        break

    try:
        answer = int(first_number) / int(second_number)
    except ZeroDivisionError:
        print("You can`t divide by zero\n")
        continue

    print(answer)

8.3.3、else代码块

执行错误的情况放在try-except代码块中,将依赖于try代码块成功执行的代码应放到else中。代码流程如下:

  1. python尝试执行try中的代码,只有可能引发异常的代码才放到try代码块中
  2. 如果运行异常,则看异常的类型是否包含在except中,如果是,则执行except代码块中代码
  3. 如果运行正常,则执行else中代码
print("Give me two numbers, and I`ll divide them.")
print("Enter 'q' to quit.")

while True:
    first_number = input("\nFirst number:\n")
    if first_number == 'q':
        break

    second_number = input("\nSecond number:\n")
    if second_number == 'q':
        break

    try:
        answer = int(first_number) / int(second_number)
    except ZeroDivisionError:
        print("You can`t divide by zero\n")
        continue
    else:
        print(answer)

8.3.4、处理FileNotFoundError异常

FileNotFoundError异常通常是由于找不到文件所引起的

filename = 'alice.txt'

try:
    with open(filename) as file_obj:
        contents = file_obj.read()
except FileNotFoundError:
    msg = 'Sorry, the file ' + filename + " does not exist."
    print(msg)

8.3.5、分析文本

分析包含整本书的文本内容

split()方法根据字符串创建一个单词列表,使用该方法一空格为分隔符将字符串拆分为多个部分,并将这部分存储到一个列表中。

filename = 'atom.txt'

try:
    with open(filename) as file_obj:
        contents = file_obj.read()
except FileNotFoundError:
    msg = 'Sorry, the file ' + filename + ' does not exist.'
    print(msg)
else:
    words = contents.split()
    num_words = len(words)
    print("The file " + filename + " has about " + str(num_words) + " words.")

8.4、存储数据

程序把客户提供的信息存储在列表和字典等数据结构中,当用户关闭程序是,需要保存这些信息,可以使用模块json来存储数据

8.4.1、json.dump()和json.load()

使用json.dump()将数据存储在文件中,使用json.load()将文件内容读取到内存中

Json.dump()有两个参数:

  • 要存储的数据
  • 可用于存储数据的文件对象
import json

numbers = [2, 3, 4, 5, 8, 21]

filename = 'numbers.json'
with open(filename, 'w') as file_obj:
    json.dump(numbers, file_obj)

    
with open(filename) as file_obj:
    numbers = json.load(file_obj)

print(numbers)

8.4.2、保存和读取用户生成的数据

对于用户生成的数据,使用json保存他们大有裨益。

import json

filename = 'username.json'


def save_user_name(filename):
    username = input("what`s your name?")

    with open(filename, 'w') as file_obj:
        json.dump(username, file_obj)
        print("we`ll remember you when you come back, " + username + "!")


def greet_user(filename):
    with open(filename) as file_obj:
        username = json.load(file_obj)
        print("hello, " + username)


save_user_name(filename)
greet_user(filename)

8.4.3、重构

代码可以正确地运行,但是可做进一步的改进——将代码划分为一系列完成具体工作的函数,这样的过程被称为重构。重构让代码更清晰,更易于理解,更容易扩展

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,753评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,668评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,090评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,010评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,054评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,806评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,484评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,380评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,873评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,021评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,158评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,838评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,499评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,044评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,159评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,449评论 3 374
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,136评论 2 356

推荐阅读更多精彩内容