从文件中读取数据

1. 读取整个文件

要读取文件,首先来创建一个文件:

然后打开并读取这个文件,再将其内容显示到屏幕上:

file_reader.py

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

解读上述代码:

  open( ) -> 要以任何方式使用文件,都首先得打开文件,这样才能访问它,此时就需要用到函数open(),该函数只接受一个参数:要打开文件的名称,同时返回表示文件的对象。

  with: 不再需要访问文件后调用 close( ) 将其关闭。

  read( ) ->读取文件中的全部内容。

运行结果:

3.1415926535
8979323946
2643383278

2. 文件路径

要让python打开不与程序文件位于同一目录中的文件,需要提供文件路径,让python到系统的特定位置去查找。

  文件路径的表示:1. 相对路径 -> 文件相对于当前运行程序所在的目录。eg. 在程序所在文件夹C:\Users\yxf\Desktop\python_pycharm新建一个文件夹text_file用于存储文件pi_digits.txt,此时就需要这样编写代码:

with open('text_files\pi_digits.txt') as file_object:

          2. 绝对文件路径 -> 文件所在完整路径。绝对路径比相对路径更长,故可将路径存储在一个变量中,再将变量传递给 open( ):

file_path = r'C:\Users\yxf\Desktop\python_pycharm\text_files\pi_digits.txt'
with open(file_path) as file_object:

由于文件路径中使用的是反斜杠,在python中被视为转义字符,故需要在开头的单引号前加上r。

3. 逐行读取

每次以一行的方式检查文件:

file_name = 'pi_digits.txt'

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

  运行结果:

3.1415926535

  8979323946

  2643383278

  通过对文件对象使用for循环来遍历文件中的每一行,但运行结果显示的每一行后边多了空白行,这是为什么呢?文件中每行的末尾都有一个看不见的换行符,而print语句也会加上一个换行符。为消除这些空白行,可在print语句中使用 rstrip( ):

print(line.rstrip())

  这样输出与文件内容就完全相同了。

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

file_name = 'pi_digits.txt'

with open(file_name) as file_object:
lines = file_object.readlines() for line in lines:
print(line.rstrip())

  方法readlines():从文件中读取每一行,并将其存储在列表中。

5. 使用文件的内容

file_name = 'pi_digits.txt'

with open(file_name) as file_object:
lines = file_object.readlines() # 将文件内容存储在列表中 pi_string = '' # 新建一个空字符串
for line in lines:
pi_string = pi_string + line.rstrip() # 删除空白行并转换为字符串 print(pi_string) # 打印字符串
print(len(pi_string)) # 打印字符串长度

  运行结果:

3.1415926535  8979323946  2643383278
36

  运行结果中包含了位于每行左边的空格,为删除这些空格,可使用 strip() 而不是 rstrip(),运行可得:

3.141592653589793239462643383278
32

6. 包含一百万位的大型数据

  一百万位的文件下载过慢,就复制使用了其中的一小部分,并打印到小数点后的50位:

file_name = 'pi_xx_digits.txt'

with open(file_name) as file_object:
lines = file_object.readlines() # 将文件内容存储在列表中 pi_string = '' # 新建一个空字符串
for line in lines:
pi_string = pi_string + line.strip() # 删除空白行并转换为字符串 print(pi_string[: 52]) # 打印字符串
print(len(pi_string)) # 打印字符串长度

  运行结果:

3.14159265358979323846264338327950288419716939937510
1483

  由运行结果可知保存了小数点后的1481位在文件 pi_xx_digits.txt 中。

7. 圆周率中包含你的生日吗

  可以检测圆周率值的前1483位中是否包含自己的生日:

file_name = 'pi_xx_digits.txt'

with open(file_name) as file_object:
lines = file_object.readlines() pi_string = ''
for line in lines:
pi_string = pi_string + line.strip() birthday = input('Enter your birthday, in the form mmddyy: ')
if birthday in pi_string:
print('Your birthday appears in the first 1483 digits of pi!')
else:
print('Your birthday does not appears in the first 1483 digits of pi.')

写入文件

  保存数据最简单的方式之一就是将其写入到文件中。通过将输出写入文件,即便关闭包含程序输出的终端窗口,这些输出依然存在:可以查看、分享或读取到内存进行处理。

1. 写入空文件

  将一条消息存储在文件中:

filename = 'programming.txt'

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

  解读代码:调用 open() 时提供了两个实参,第一个实参是要打开文件的名称;第二个实参('w')表示以写入模式打开这个文件。

    打开文件时,可指定读取模式('r')、写入模式('w')、附加模式('a')、读取和写入模式('r+')。

    省略模式实参,默认以只读模式打开文件。

    写入文件不存在时,函数 open() 将自动创建;但若指定文件已经存在,python将在返回文件对象前清空该文件,即新的写入内容会覆盖旧的。

  运行程序之后:会在程序文件所在目录发现新增了一个名为 programming.txt 的文件,打开该文件将看到其中包含如下的内容:

I love programming.

  Note: Python中只能将字符串写入文本文件。要存储数据时,必须先使用函数将其转换为字符串格式。

2. 写入多行

filename = 'programming.txt'

with open(filename, 'w') as file_object:
file_object.write("I love programming.\n") # 写入第一行内容,为避免内容挤在一起,用‘\n’换行
file_object.write("I love creating new games.\n") # 写入第二行

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

3. 附加到文件

filename = 'programming.txt'

with open(filename, 'a') as file_object:
file_object.write("I also love finding meaning in large datasets.\n")
file_object.write("I love creating apps that can run in a browser.\n")

  以附加模式打开文件,若文件本存在,将写入内容添加到文件末尾;文件不存在,则新创建一个写入内容。

异常

  每当发生让python不知所措的错误的时候,都会创建一个异常对象。如果编写了处理处理改异常的代码,程序将继续运行,如果未对异常处理,程序将停止,并显示一个traceback,其中包含有关异常的报告。

  异常使用 try - except 代码块处理,执行指定操作的同时告诉python发生异常了怎么办。

1. 处理ZeroDivisionError异常

print(3/0)

  被除数时不能为0的,但在python中为0了会怎么呢?

Traceback (most recent call last):
File "division.py", line 1, in <module>
print(3/0)
ZeroDivisionError: division by zero

  python停止运行,并指出引发了哪种异常。发生异常也希望程序能继续运行怎么办呢?

2. 使用 try - except 代码块

  当有可能发生错误时,可编写一个 try - except 代码块来处理可能引发的异常:

try:
print(3/0)
except ZeroDivisionError:
print("You can't divide by zero!")

  运行结果:

You can't divide by zero!

3. 使用异常避免崩溃

  发生错误时,如果程序还有工作没完成,妥善处理错误就尤为重要。

# 一个只执行除法运算的简单计算器
print("Give me two numbers, and I'll divide them.")
print("Enter 'q' to quit.") while True:
first_number = input("\nFirst number: ")
if first_number == 'q':
break
second_number = input("Second number: ")
if second_number == 'q':
break
answer = int(first_number)/int(second_number)
print(answer)

  如果用户给第二个数字输入0,就会出现:

Traceback (most recent call last):
File "division.py", line 12, in <module>
answer = int(first_number)/int(second_number)
ZeroDivisionError: division by zero

  这样的信息会把不懂技术的用户搞糊;会对怀有恶意的用户暴露重要信息。

4. else代码块

# 一个只执行除法运算的简单计算器
print("Give me two numbers, and I'll divide them.")
print("Enter 'q' to quit.") while True:
first_number = input("\nFirst number: ")
if first_number == 'q':
break
second_number = input("Second number: ")
if second_number == 'q':
break
try:
answer = int(first_number)/int(second_number)
except ZeroDivisionError:
print("You can't divide by zero!")
else:
print(answer)

  运行结果:

Give me two numbers, and I'll divide them.
Enter 'q' to quit. First number: 3
Second number: 0
You can't divide by zero! First number: 4
Second number: 2
2.0 First number: q

  尝试执行 try 代码块中的代码:若引发了异常,执行except代码块的代码;若没有发生异常,执行else代码块。

5. 处理FileNotFoundError异常

  使用文件时,最常见的问题就是找不到文件:文件可能在其他地方、文件名可能不对或者文件就不存在。尝试读取一个不存在的文件:

filename = 'alice.txt'

with open(filename) as f_obj:
contents = f_obj.read()

  运行结果:

Traceback (most recent call last):
File "alice.py", line 3, in <module>
with open(filename) as f_obj:
FileNotFoundError: [Errno 2] No such file or directory: 'alice.txt'

  上述代码运行错误是函数open()导致的,因此要处理这个错误,必须把try语句放在包含open()的代码前:

filename = 'alice.txt'

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

  运行结果:

Sorry, the file alice.txt does not exist.

  告知用户文件不存在。

6. 分析文本

  分析包含整本书的文本文件: 在网站http://www.gutenberg.org/下载文学文本The Lay of the Nibelung Men.txt,提取文本,并尝试计算包含了多少个单词:

filename = 'The-Lay-of-the-Nibelung-Men.txt'
try:
with open(filename) as f_obj:
contents = f_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.")

  运行结果:

The file The-Lay-of-the-Nibelung-Men.txt has about 124918 words.

7. 使用多个文件

def count_words(filename):
"""计算一个文件大致包含多少个单词"""
try:
with open(filename) as f_obj:
contents = f_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.")

  定义一个可以计算文件有多少单词的函数,之后就可调用该函数来计算多个文件的:

filenames = ['A-Case-of-Sunburn.txt', 'moby_dick.txt', 'The-Lay-of-the-Nibelung-Men.txt']
for filename in filenames:
count_words(filename)

  运行结果:

The file A-Case-of-Sunburn.txt has about 9416 words.
Sorry, the file moby_dick.txt does not exist.
The file The-Lay-of-the-Nibelung-Men.txt has about 124918 words.

8. 失败时一声不吭

  若希望在不捕获到异常时一声不吭,继续执行:

try:
...
except FileNotFoundError:
pass
else:
...

  在捕获到异常时,执行pass语句。

存储数据

  很多程序都要求用户输入某种信息,程序把用户提供的信息存储在列表和字典等数据结构中。用户关闭程序时,就要保存提供的信息,一种简单的方式就是使用模块json来存储数据。

  模块json能将简单的python数据结构存储到文件中,并在程序再次运转时加载该文件中的数据。还可以使用json在python程序之间分享数据,与使用其他编程语言的人分享。

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

import json

numbers = [2, 3, 5, 7, 11, 13]

filename = 'number.json'
with open(filename, 'w') as f_ojb: # 以写入模式打开文件
json.dump(numbers, f_ojb) # 使用函数json.dump()将列表存储到文件中 with open(filename) as f_ojb:
nums = json.load(f_ojb) # 使用函数json.load()将这个列表读取到内存中 print(nums) # 打印读取到内存中的列表,比较是否与存入的列表相同

  运行结果:

[2, 3, 5, 7, 11, 13]

2. 保存和读取用户生成的数据

import json

# 存储用户的名字
username = input('What is your name? ')
filename = 'username.json'
with open(filename, 'w') as f_obj:
json.dump(username, f_obj) # 存储用户名与username.json文件中
print("We'll remember you when you come back, " + username + "!") # 向名字被存储的用户发出问候
with open(filename) as f_obj:
un = json.load(f_obj)
print("\nWelcome back, " + un + "!")

  运行结果:

What is your name? ela
We'll remember you when you come back, ela! Welcome back, ela!

  优化上述代码:

import json

# 若存储了用户名就加载;否则提示用户输入并存储
filename = 'username.json'
try:
with open(filename) as f_obj:
username = json.load(f_obj)
except FileNotFoundError:
username = input('What is your name? ')
with open(filename, 'w') as f_obj:
json.dump(username, f_obj)
print("We'll remember you when you come back, " + username + "!")
else:
print("\nWelcome back, " + username + "!")

  运行结果:

Welcome back, ela!

3. 重构

  代码可以运行,但也可以做进一步改进——将代码划分成一些列完成具体工作的函数:这个过程称为重构。

  目的:让代码更清晰、易于理解、易扩展。

import json

def get_stored_username():
"""如果存储了用户名,就获取它"""
filename = 'username.json'
try:
with open(filename) as f_obj:
username = json.load(f_obj)
except FileNotFoundError:
return None
else:
return username def get_new_username():
"""提示用户输入用户名"""
username = input('What is your name? ')
filename = "username.json"
with open(filename, 'w') as f_obj:
json.dump(username, f_obj)
return username def greet_user():
"""问候用户,并指出其名字"""
username = get_stored_username()
if username:
print("Welcome back, " + username + "!")
else:
username = get_new_username()
print("We'll remember you when you come back, " + username + "!") greet_user()

  敲代码的时候忘了最后一行greet_user(),就说怎么运行程序都么有结果,哈哈哈!!!

文件和异常——python从编程入门到实践的更多相关文章

  1. Python游戏编程入门

    <Python游戏编程入门>这些文章负责整理在这本书中的知识点.注意事项和课后习题的尝试实现.并且对每一个章节给出的最终实例进行分析和注释. 初识pygame:pie游戏pygame游戏库 ...

  2. Python+Selenium基础入门及实践

    Python+Selenium基础入门及实践 32018.08.29 11:21:52字数 3220阅读 23422 一.Selenium+Python环境搭建及配置 1.1 selenium 介绍 ...

  3. Linux 利器- Python 脚本编程入门(一)

    导读 众所周知,系统管理员需要精通一门脚本语言,而且招聘机构列出的职位需求上也会这么写.大多数人会认为 Bash (或者其他的 shell 语言)用起来很方便,但一些强大的语言(比如 Python)会 ...

  4. Python游戏编程入门 中文pdf扫描版|网盘下载内附地址提取码|

    Python是一种解释型.面向对象.动态数据类型的程序设计语言,在游戏开发领域,Python也得到越来越广泛的应用,并由此受到重视. 本书教授用Python开发精彩游戏所需的[]为重要的该你那.本书不 ...

  5. python socket编程入门(编写server实例)+send 与sendall的区别与使用方法

    python 编写server的步骤: 1. 第一步是创建socket对象.调用socket构造函数.如: socket = socket.socket( family, type ) family参 ...

  6. Python游戏编程入门2

    I/O.数据和字体:Trivia游戏 本章包括如下内容:Python数据类型获取用户输入处理异常Mad Lib游戏操作文本文件操作二进制文件Trivia游戏 其他的不说,我先去自己学习文件类型和字符串 ...

  7. Python快速编程入门,打牢基础必须知道的11个知识点 !

    Python被誉为全世界高效的编程语言,同时也被称作是“胶水语言”,那它为何能如此受欢迎,下面我们就来说说Python入门学习的必备11个知识点,也就是它为何能够如此受欢迎的原因. Python 简介 ...

  8. python编程学习--Pygame - Python游戏编程入门(0)---转载

    原文地址:https://www.cnblogs.com/wuzhanpeng/p/4261015.html 引言 博客刚开,想把最近学习的东西记录下来,算是一种笔记.最近打算开始学习Python,因 ...

  9. Pygame - Python游戏编程入门(0) 转

    博客刚开,想把最近学习的东西记录下来,算是一种笔记.最近打算开始学习Python,因为我感觉Python是一门很有意思的语言,很早以前就想学了(碍于懒),它的功能很强大,你可以用它来做科学运算,或者数 ...

随机推荐

  1. Tips on Python

    python是一种解释性文件,代码要通过解释器解释运行.python解释器就是python.exe这个程序. pip也是一个pip.exe的程序,是用来管理python的第三方库. 有两种执行方式:脚 ...

  2. c++读写matlab中.mat数据

    前言:在进行图形图像处理时,经常会用到matlab进行算法的仿真验证,然后再移植到别的语言中.有时会涉及到数据的交互,比如直接读取matlab的.mat类型数据,或者是将c++中的数组存为.mat,为 ...

  3. asp.net Web 项目的文件/文件夹上传下载

    以ASP.NET Core WebAPI 作后端 API ,用 Vue 构建前端页面,用 Axios 从前端访问后端 API ,包括文件的上传和下载. 准备文件上传的API #region 文件上传  ...

  4. vue-cli3 ios10白屏问题解决思路

    在出现了这个问题之后先不要盲目的去瞎试,根据网上的方法试了个遍也没解决问题 先看报的是什么错,再针对的解决问题 首先出现的报错是 SyntaxError: Unexpected token '*'  ...

  5. “知乎杯”2018 CCF 大学生计算机系统与程序设计竞赛 贪心算法(greedy)

    --> 贪心算法 1)题解 •        分别用V0.V1和V>=2表示度为0.1以及至少为2的顶点集合 •        对于每个顶点,维护三个属性: •        degree ...

  6. Ajax.BeginForm 不执行OnSuccess

    今天用MVC做了一个表单提交,使用Ajax.BeginForm ,但是碰到一个奇怪的问题OnSuccess回调函数不执行.后来经过多次尝试才发现要引用两个东西 1.<script src=&qu ...

  7. Clouds Classification from Sentinel-2 Imagery with Deep Residual Learning and Semantic Image Segmentation

    哨兵2号云检测的语义分割,提出了CloudNet,不使用池化和上采样操作,从头到尾保持原图大小,中间每个块使用ASPP和残差连接,网络结构如下 比较了CNN, FCN, DeeplabV3+,效果都没 ...

  8. P3709 大爷的字符串题(莫队+结论)

    题目 P3709 大爷的字符串题 做法 有一个显然的结论:一段区间里最小答案为众数的个数 用莫队来离线求众数 \(tmp_i\)表示出现\(i\)次的数的个数,\(num_i\)表示\(i\)出现的次 ...

  9. pxe问题

    可能镜像路径问题 https://blog.csdn.net/geek_tank/article/details/69479196 一.vmlinuz vmlinuz是可引导的.压缩的内核.“vm”代 ...

  10. Net core学习系列(二)——Net Core项目文件简介

    一. ASP.NET Core 项目文件夹解读 ASP.NET Core 1.0 发布以来,相较于传统项目编码发布的行为,新项目中的操作已经有了很大的变化,如解析依赖,选择运行平台和Runtime等等 ...