Skip to content

06 文件、异常处理与JSON

文件输入输出(File IO)

文件输入输出(File IO)是指程序与外部存储设备(如硬盘、SSD等)之间进行数据交换的过程。在Python中,文件IO操作使得程序能够读取、写入和修改文件内容,从而实现数据的持久化存储和管理。

文件是什么

文件是用于存储数据的基本单位,可以是文本文件、二进制文件、图片、音频、视频等各种类型。文件通常由文件名和扩展名组成,用于标识文件的类型和内容。例如:

  • document.txt:文本文件
  • image.jpg:JPEG图片文件
  • data.json:JSON数据文件

文件的基本特性:

  • 持久性:文件存储在磁盘上,数据在程序运行结束后依然存在。
  • 有序性:文件中的数据是有序排列的,可以按顺序读取。
  • 随机访问:可以在文件的任意位置读取或写入数据。

文件路径

文件路径用于定位文件在文件系统中的位置。文件路径分为绝对路径和相对路径。

  • 绝对路径:从根目录开始,完整描述文件的位置。例如:
  • Windows: C:\Users\Username\Documents\file.txt
  • Unix/Linux: /home/username/documents/file.txt

  • 相对路径:相对于当前工作目录的位置。例如,如果当前工作目录是/home/username/,相对路径documents/file.txt指向/home/username/documents/file.txt

路径分隔符:

  • Windows 使用反斜杠 \ 作为路径分隔符。
  • Unix/Linux 和 macOS 使用正斜杠 / 作为路径分隔符。

跨平台路径处理:

为了编写跨平台的代码,可以使用Python的os模块中的os.path子模块或pathlib模块来处理路径。

import os

# 使用os.path拼接路径
file_path = os.path.join("documents", "file.txt")
print(file_path)  # 在Unix/Linux: documents/file.txt, 在Windows: documents\file.txt

Python 的文件操作

Python提供了丰富的内置函数和模块来处理文件操作,主要通过open()函数来打开文件,并进行读写操作。

写入文件

写入文件是指将数据写入到文件中。Python中使用open()函数以特定模式打开文件,然后使用文件对象的write()writelines()方法进行写入。

常用的文件打开模式:

  • 'r':读取模式(默认)
  • 'w':写入模式,覆盖文件内容
  • 'b':二进制模式

示例:写入文本文件

# 以写入模式打开文件,如果文件不存在则创建
with open('output.txt', 'w', encoding='utf-8') as file:
    file.write("Hello, World!\n")
    file.write("这是一个示例文件。\n")

示例:写入多行内容

lines = ["第一行\n", "第二行\n", "第三行\n"]
with open('output.txt', 'w', encoding='utf-8') as file:
    file.writelines(lines)

上下文管理器(with语句)

在进行文件操作时,确保文件在使用完毕后正确关闭是非常重要的。使用with语句可以简化文件操作,并自动管理文件的打开和关闭,避免资源泄漏。

示例:使用with语句读取文件

# 使用with语句读取文件内容
with open('output.txt', 'r', encoding='utf-8') as file:
    content = file.read()
    print(content)

示例:使用with语句写入文件

# 使用with语句写入文件
with open('output.txt', 'w', encoding='utf-8') as file:
    file.write("使用with语句写入内容。\n")

优点:

  • 自动关闭文件,无需手动调用file.close()
  • 更简洁、易读的代码
  • 避免因异常导致文件未关闭的问题

异常处理

在编程过程中,程序可能会遇到各种错误和异常情况,如文件不存在、用户输入错误、网络连接失败等。异常处理机制使得程序能够优雅地应对这些问题,防止程序崩溃,并提供有意义的反馈。

什么是异常?

异常是程序在运行过程中发生的错误事件。当Python解释器检测到错误时,会生成一个异常对象,并中断当前的执行流程,除非该异常被捕获并处理。

常见的异常类型:

  • SyntaxError:语法错误
  • TypeError:类型错误
  • ValueError:值错误
  • FileNotFoundError:文件未找到错误
  • ZeroDivisionError:除以零错误
  • IndexError:索引超出范围错误

示例:触发异常

# 除以零错误
result = 10 / 0  # ZeroDivisionError

异常和异常处理的重要性

异常处理的重要性体现在以下几个方面:

  1. 提高程序的健壮性:通过捕获和处理异常,程序可以在遇到错误时继续运行,而不是突然崩溃。
  2. 提供用户友好的反馈:可以向用户提供明确的错误信息,帮助他们理解问题所在。
  3. 便于调试和维护:合理的异常处理可以帮助开发者快速定位和修复问题。
  4. 资源管理:确保在出现异常时,资源(如文件、网络连接)能够被正确释放,避免资源泄漏。

如何处理?

Python使用try-except语句来处理异常。基本结构如下:

try:
    # 可能会引发异常的代码块
    risky_operation()
except SpecificException as e:
    # 处理特定异常
    handle_exception(e)
except AnotherException as e:
    # 处理另一个特定异常
    handle_another_exception(e)
except Exception as e:
    # 处理所有其他异常
    handle_generic_exception(e)
else:
    # 如果try块没有引发异常,则执行else块
    execute_if_no_exception()
finally:
    # 无论是否引发异常,都会执行finally块
    cleanup_operations()

关键部分解释:

  • try:包含可能引发异常的代码。
  • except:定义如何处理特定的异常。
  • else:当try块没有引发任何异常时执行。
  • finally:无论是否发生异常,都会执行的代码,通常用于资源清理。

示例:捕获文件未找到异常

try:
    with open('nonexistent_file.txt', 'r', encoding='utf-8') as file:
        content = file.read()
except FileNotFoundError as e:
    print(f"错误: {e}")
else:
    print("文件读取成功。")
finally:
    print("文件操作结束。")

输出:

错误: [Errno 2] No such file or directory: 'nonexistent_file.txt'
文件操作结束。

示例:捕获用户输入错误

try:
    age = int(input("请输入你的年龄: "))
    print(f"你的年龄是 {age} 岁。")
except ValueError:
    print("输入无效,请输入一个整数。")

使用多个except块处理不同异常

try:
    value = int(input("请输入一个整数: "))
    result = 10 / value
except ValueError:
    print("输入无效,请输入一个整数。")
except ZeroDivisionError:
    print("错误:除数不能为零。")
except Exception as e:
    print(f"发生未知错误: {e}")
else:
    print(f"结果是 {result}")
finally:
    print("程序结束。")

JSON

JSON简介

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。它基于JavaScript的对象表示法,但独立于语言,广泛应用于Web开发、API通信、配置文件等场景。

JSON的基本结构:

  • 对象:由花括号 {} 包围,包含键值对。例如:
    {
        "name": "Alice",
        "age": 30
    }
    
  • 数组:由方括号 [] 包围,包含有序的值。例如:
    ["apple", "banana", "cherry"]
    

JSON支持的数据类型:

  • 字符串(String)
  • 数字(Number)
  • 对象(Object)
  • 数组(Array)
  • 布尔值(Boolean)
  • 空值(null)

概念与用途

概念:

JSON以键值对的形式存储和传输数据,具有结构化和层次化的特点。它的语法简洁,易于理解和使用,成为现代应用程序中数据交换的标准格式之一。

用途:

  1. Web API通信:客户端和服务器之间通过JSON格式传输数据。
  2. 配置文件:应用程序使用JSON文件存储配置信息,便于管理和修改。
  3. 数据存储:将结构化数据存储为JSON格式,便于读取和处理。
  4. 前后端数据交互:前端应用(如JavaScript)与后端服务之间通过JSON进行数据交换。

示例:一个包含用户信息的JSON对象

{
    "username": "john_doe",
    "email": "[email protected]",
    "age": 28,
    "is_active": true,
    "roles": ["admin", "user"]
}

使用json模块

Python内置的json模块提供了简单易用的方法来处理JSON数据,包括序列化(将Python对象转换为JSON)和反序列化(将JSON数据转换为Python对象)。

json.load()json.loads()

  • json.load(file):从文件读取JSON数据并反序列化为Python对象。
  • json.loads(json_string):从字符串读取JSON数据并反序列化为Python对象。

示例:使用json.load()读取JSON文件

假设有一个data.json文件内容如下:

{
    "name": "Alice",
    "age": 30,
    "is_student": false,
    "courses": ["Math", "Science"]
}
import json

# 从文件读取JSON数据
with open('data.json', 'r', encoding='utf-8') as file:
    data = json.load(file)

print(data)
# 输出: {'name': 'Alice', 'age': 30, 'is_student': False, 'courses': ['Math', 'Science']}

示例:使用json.loads()解析JSON字符串

import json

json_str = '''
{
    "name": "Bob",
    "age": 25,
    "is_student": true,
    "courses": ["History", "Art"]
}
'''

# 解析JSON字符串
data = json.loads(json_str)

print(data)
# 输出: {'name': 'Bob', 'age': 25, 'is_student': True, 'courses': ['History', 'Art']}

json.dump()json.dumps()

  • json.dump(obj, file):将Python对象序列化为JSON格式并写入文件。
  • json.dumps(obj):将Python对象序列化为JSON格式的字符串。

示例:使用json.dump()写入JSON文件

import json

data = {
    "name": "Charlie",
    "age": 22,
    "is_student": True,
    "courses": ["Physics", "Chemistry"]
}

# 将Python对象写入JSON文件
with open('output.json', 'w', encoding='utf-8') as file:
    json.dump(data, file, ensure_ascii=False, indent=4)

print("JSON数据已写入output.json")

ensure_ascii=False:确保非ASCII字符(如中文)能够正确写入文件。

indent=4:使JSON数据具有良好的可读性,缩进4个空格。

示例:使用json.dumps()生成JSON字符串

import json

data = {
    "name": "Diana",
    "age": 27,
    "is_student": False,
    "courses": ["Biology", "English"]
}

# 将Python对象转换为JSON字符串
json_str = json.dumps(data, ensure_ascii=False, indent=4)
print(json_str)

输出:

{
    "name": "Diana",
    "age": 27,
    "is_student": false,
    "courses": [
        "Biology",
        "English"
    ]
}

注意事项:

  • 数据类型对应
  • dict对应JSON的对象
  • listtuple对应JSON的数组
  • str对应JSON的字符串
  • intfloat对应JSON的数字
  • True/False对应JSON的true/false
  • None对应JSON的null

综合练习:日志记录系统

设计并实现一个简单的日志记录系统。该系统需要完成以下功能:

  • 接受用户输入的日志消息。
  • 将日志消息写入app.log文件,每条日志前添加时间戳。
  • 如果app.log文件不存在,程序应自动创建。
  • 处理文件写入过程中的异常,确保程序不会因错误而崩溃。

要求: - 使用with语句进行文件操作。 - 使用try-except块捕获并处理可能的异常。

日志格式示例:

2024-04-27 15:30:45 - 应用程序启动。
2024-04-27 15:31:10 - 用户登录成功。