文件和异常

章节目录:

    • 一、从文件中读取数据
      • 1.1 读取整个文件
      • 1.2 文件路径
      • 1.3 逐行读取
    • 二、文件写入
    • 三、通过 json 模块存储数据
    • 四、异常
    • 五、异常处理
      • 5.1 try / except
      • 5.2 try / except...else
      • 5.3 try / finally
    • 六、抛出异常
    • 七、用户自定义异常
    • 八、结束语

一、从文件中读取数据

1.1 读取整个文件

  • 包层级目录
# 程序和文件都在同一层目录。
E:\PYCODES
|   data.txt
|   sample.py
  • data.txt 文件内容
hello
world
  • 代码示例
# 方式一:需要手动关闭文件。
file = open("data.txt", "r")
content = file.read()
file.close()
print(content)
# hello
# world

print("---------------")

# 方式二:自动关闭文件(更安全的做法)。
with open("data.txt") as file_object:
    contents = file_object.read()
    print(contents)
    # hello
    # world

1.2 文件路径

  • 相对路径读取
# 文件在程序的上一层,可通过路径通配符读取相对路径。
# 路径盘符。(Unix:正斜线(/);windows:反斜线(\))
path = "..\\test.txt"
with open(path, encoding="UTF-8") as file_object:
    contents = file_object.read()
    print(contents)
    # 我在上一级目录。

  • 绝对路径读取
# 文件,可通过绝对路径进行读取。
path = "D:\\a\\test.txt"
with open(path, encoding="UTF-8") as file_object:
    contents = file_object.read()
    print(contents)
    # 我在其他路径下。

1.3 逐行读取

  • 代码示例
path = "data.txt"
with open(path, encoding="UTF-8") as file_object:
    for line in file_object:
        # 换行符会被读取。
        print(line)
        # hello
        #
        # world

  • 去除换行符
path = "data.txt"
with open(path, encoding="UTF-8") as file_object:
    for line in file_object:
        # rstrip() 去掉换行。
        print(line.rstrip())
        # hello
        # world

二、文件写入

  • 写入空文件
# 文件不存在则会创建。
filename = "sample.txt"

# w 为写入模式。
with open(filename, "w") as file_object:
    file_object.write("I love programming.")

  • 写入多行
filename = "sample.txt"

with open(filename, "w") as file_object:
    # 多行时需要添加换行符。
    file_object.write("I love programming.\n")
    file_object.write("I love programming.\n")

  • 追加写入
filename = "sample.txt"

# a 为追加写入模式。
with open(filename, "a") as file_object:
    file_object.write("I love programming.\n")
    file_object.write("I love programming.\n")

三、通过 json 模块存储数据

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

  • 代码示例
import json

# 准备要写入文件的数据。
data = {
    "name": "jan",
    "age": 18
}

# 文件名。
file_name = "test.json"

with open(file_name, "w") as file_object:
    # 写入 json 数据。
    json.dump(data, file_object)

with open(file_name, "r") as file_object:
    # 读取 json 数据。
    contents = json.load(file_object)

print("read contents={}".format(contents))
# read contents={'name': 'jan', 'age': 18}

四、异常

即便 Python 程序的语法是正确的,在运行它的时候,也有可能发生错误。运行期检测到的错误被称为异常。

  • 常见异常类型
# 0 不能作为除数,触发异常
>>> 10 * (1/0)             
Traceback (most recent call last):
  File "", line 1, in ?
ZeroDivisionError: division by zero

# spam 未定义,触发异常
>>> 4 + spam*3             
Traceback (most recent call last):
  File "", line 1, in ?
NameError: name 'spam' is not defined

# int 不能与 str 相加,触发异常
>>> '2' + 2               
Traceback (most recent call last):
  File "", line 1, in <module>
TypeError: can only concatenate str (not "int") to str
  • 异常以不同的类型出现,这些类型都作为信息的一部分打印出来: 例子中的类型有 ZeroDivisionError,NameError 和 TypeError。
  • 错误信息的前面部分显示了异常发生的上下文,并以调用栈的形式显示具体信息。

五、异常处理

5.1 try / except

  • 句式
try:
    # 执行的代码。
except Exception:
    # 发生异常时执行的代码。
  • 代码示例
try:
    # 使其触发异常。
    print(2 / 0)
except ZeroDivisionError:
    print("除数不能为0!")
    # 除数不能为0!

  • 一个 try 语句可能包含多个 except 子句,分别来处理不同的特定的异常。最多只有一个分支会被执行
  • 处理程序将只针对对应的 try 子句中的异常进行处理,而不是其他的 try 的处理程序中的异常。
  • 一个 except 子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,例如:
except (RuntimeError, TypeError, NameError):
    pass

5.2 try / except…else

try/except 语句还有一个可选的 else 子句,如果使用这个子句,那么必须放在所有的 except 子句之后。

  • 句式
try:
    # 执行的代码。
except Exception:
    # 发生异常时执行的代码。
else:
    # 没有发生异常时执行的代码。
  • 使用 else 子句把所有的语句都放在 try 子句里面要好,这样可以避免一些意想不到,而 except 又无法捕获的异常
  • 异常处理并不仅仅处理那些直接发生在 try 子句中的异常,而且还能处理子句中调用的函数(甚至间接调用的函数)里抛出的异常。例如
def division_by_zero():
    return 2 / 0


try:
    # 被调用的函数内部发生异常。
    result = division_by_zero()
# 异常则提示。
except ZeroDivisionError:
    print("除数不能为0!")
    # 除数不能为0!
except TypeError:
    print("类型错误!")
else:
    # 没有异常则打印返回结果。
    print("result=" + str(result))

5.3 try / finally

try / finally 语句无论是否发生异常都将执行最后的代码。

  • 句式
try:
    # 执行的代码。
except Exception:
    # 发生异常时执行的代码。
else:
    # 没有发生异常时执行的代码。
finally:
    # 无论如何都会执行。
  • 代码示例
try:
    result = 2 + 2
except ZeroDivisionError:
    print("除数不能为0!")
except TypeError:
    print("类型错误!")
else:
    print("result=" + str(result))
    # result=4
finally:
    print("这句代码无论如何都会被执行!")
    # 这句代码无论如何都会被执行!

六、抛出异常

Python 使用 raise 语句抛出一个指定的异常。

  • 句式
raise [Exception [, args [, traceback]]]
  • 代码示例
num = 1
if num < 2:
    raise Exception("数字不能小于2!当前值为{}。".format(num))
    # Exception: 数字不能小于2!当前值为1。

七、用户自定义异常

  • 可以通过创建一个新的异常类来拥有自己的异常。异常类继承Exception 类,可以直接继承,或者间接继承,例如:
class MyError(Exception):

    #  Exception 默认的 __init__() 被覆盖。
    def __init__(self, msg):
        self.msg = msg


try:
    raise MyError("捕获到了自定义异常!")
except MyError as e:
    # 打印异常信息。
    print(e.msg)
    # 捕获到了自定义异常!

  • 当创建一个模块有可能抛出多种不同的异常时,一种通常的做法是为这个包建立一个基础异常类,然后基于这个基础类为不同的错误情况创建不同的子类:
# 异常基类。
class Error(Exception):
    pass


# 自定义异常子类。
class InputError(Error):
    def __init__(self, expression, message):
        self.expression = expression
        self.message = message


# 自定义异常子类。
class TransitionError(Error):
    def __init__(self, previous, next, message):
        self.previous = previous
        self.next = next
        self.message = message

  • 大多数的异常的名字都以"Error"结尾,就跟标准的异常命名一样。

八、结束语


“-------怕什么真理无穷,进一寸有一寸的欢喜。”

微信公众号搜索:饺子泡牛奶

你可能感兴趣的:(Python,python)