Python文件操作

文件读写

模式字符含义与功能
'r'只读模式(默认模式)。文件必须存在,否则会抛出 FileNotFoundError 6,7,8
'w'写入模式。如果文件不存在,则创建新文件;如果文件存在,则清空其内容后写入 6,7,8
'x'独占创建模式。文件不存在时创建新文件;如果文件已存在,则操作失败并抛出 FileExistsError 6,7
'a'追加模式。如果文件不存在,则创建新文件;如果文件存在,则在文件末尾追加内容,不会清空原有数据 6,7,8
'+'更新模式(读写模式)。允许同时进行读写操作,需与其他模式结合使用,如 'r+'(读写,文件必须存在)、'w+'(读写,创建新文件或清空已有文件内容)或 'a+'(追加读写) 7,8

基础用法

f = open('example.txt', 'w', encoding='utf-8')
f.write("hello world")
f.close() # 关闭文件之前会先flush,将缓冲区内容刷新到磁盘中

常见用法

# with 用法最后自动close
    with open('example.txt', 'w', encoding='utf-8') as f:
        f.write('Hello, World!\n')
        f.writelines(['Line 1\n', 'Line 2\n'])
    
    # 读取文件
    with open('example.txt', 'r', encoding='utf-8') as f:
        content = f.read()          # 读取全部内容
        content = f.read(2)          # 读取文件前2个字符
        lines = f.readlines()       # 读取所有行
        line = f.readline()         # 读取一行
    
    # 逐行读取(推荐用于大文件)
    with open('example.txt', 'r', encoding='utf-8') as f:
        for line in f:
            print(line.strip())

文件路径

import os
from pathlib import Path

# 使用 os.path
file_path = "data/example.txt"
print(os.path.abspath(file_path))    # 绝对路径
print(os.path.dirname(file_path))    # 目录名
print(os.path.basename(file_path))   # 文件名
print(os.path.exists(file_path))     # 是否存在

# 使用 pathlib(推荐)
path = Path('data/example.txt')
print(path.absolute())              # 绝对路径
print(path.parent)                  # 父目录
print(path.name)                    # 文件名
print(path.suffix)                  # 文件后缀
print(path.exists())                # 是否存在

异常处理

基本语法结构

try:
    # 可能抛出异常的代码
    result = 10 / 0
except ZeroDivisionError:
    # 处理特定异常
    print("不能除以零!")
except (ValueError, TypeError) as e:
    # 处理多个异常
    print(f"值或类型错误: {e}")
except Exception as e:
    # 处理所有其他异常
    print(f"发生错误: {e}")
else:
    # 没有异常时执行
    print("操作成功!")
finally:
    # 无论是否异常都会执行
    print("清理资源")

常见内置异常类型

# 基础异常类
BaseException
 ├── SystemExit
 ├── KeyboardInterrupt
 ├── GeneratorExit
 └── Exception
      ├── ArithmeticError
      │    ├── ZeroDivisionError
      │    └── FloatingPointError
      ├── AssertionError
      ├── AttributeError
      ├── EOFError
      ├── ImportError
      ├── LookupError
      │    ├── IndexError
      │    └── KeyError
      ├── NameError
      ├── OSError
      │    ├── FileNotFoundError
      │    ├── PermissionError
      │    └── TimeoutError
      ├── RuntimeError
      ├── SyntaxError
      ├── TypeError
      └── ValueError

自定义异常

class CustomError(Exception):
    """自定义异常类"""
    
    def __init__(self, message, code=None):
        super().__init__(message)
        self.code = code
    
    def __str__(self):
        if self.code:
            return f"[{self.code}] {super().__str__()}"
        return super().__str__()

# 使用自定义异常
def validate_age(age):
    if age < 0:
        raise CustomError("年龄不能为负数", "AGE_NEGATIVE")
    if age > 150:
        raise CustomError("年龄不合理", "AGE_TOO_LARGE")
    return True

try:
    validate_age(-5)
except CustomError as e:
    print(f"验证失败: {e}")

Python 模块系统

模块说白了就是Python文件,里面有函数、自定义类、变量,可以被其他Python程序引用

模块的创建和导入

  1. 创建模块,需要说明的是,在其他Python程序中导入模块,也会自顶向下顺序执行被导入模块的程序,可以把一些在被其他程序导入的时候不想被执行也不想删除的程序放在if __name__ == "__main__": 中,因为被导入时,这个表达式不成立就不会执行

  2. 在IDE中右键点运行的时候if __name__ == "__main__": 这个表达式是成立的,所以这个表达式内部的程序会被执行,当然这个并不是Python文件的入口程序,程序也是自顶向下运行的。

    # mymodule.py
    """这是一个示例模块"""
    MODULE_VERSION = "1.0.0"
    def greet(name):
        """打招呼函数"""
        return f"Hello, {name}!"
    
    class Calculator:
        """简单的计算器类"""
        
        @staticmethod
        def add(a, b):
            return a + b
    
    # 模块测试代码
    if __name__ == "__main__":
        print(greet("World"))
        print(f"面积: {calculate_area(5)}")
    
  3. 导入模块的不同方式

    # 1. 导入整个模块
    import mymodule
    result = mymodule.greet("Alice")
    
    # 2. 导入特定函数/类
    from mymodule import greet, Calculator
    result = greet("Bob")
    calc = Calculator()
    
    # 3. 导入并重命名
    from mymodule import greet as hello
    import mymodule as mm
    
    # 4. 导入所有内容(不推荐)
    from mymodule import *
    
    # 5. 相对导入(在包内使用)
    from . import submodule   # 从当前包内找到导入
    from .. import parent_module  # 从父级包中找包导入
    

模块搜索路径

  1. 在程序执行时,解释器会在sys.path列表中查找Python包和模块,我们可以在程序执行中为sys.path添加自定义路径。

    import sys
    
    # 查看模块搜索路径
    print("模块搜索路径:")
    for path in sys.path:
        print(f"  {path}")
    # 添加自定义路径
    sys.path.append('/path/to/your/modules')
    
    # 查看已加载的模块
    print("\n已加载的模块:")
    for name in sorted(sys.modules.keys()):
        if not name.startswith('_'):
            print(f"  {name}")
    

Python包管理

包的结构和创建

my_package/
├── __init__.py          # 包初始化文件
├── module1.py          # 模块1
├── module2.py          # 模块2
├── subpackage1/        # 子包1
│   ├── __init__.py
│   └── submodule1.py
├── subpackage2/        # 子包2
│   ├── __init__.py
│   └── submodule2.py
└── tests/              # 测试目录
    └── test_module1.py

init.py文件作用

主要作用简要说明
标识包身份告诉Python解释器该目录应被视为一个(Package),而非常规文件夹。
初始化模块在包被导入时,该文件中的代码会首先自动执行,可用于设置包级别的变量、配置日志、建立数据库连接等初始化操作。
简化导入路径可以在文件内导入包下的模块、函数或类,为用户提供更简洁清晰的顶层API接口。
控制导入行为通过定义 __all__ 列表,精确控制 from package import * 语句会导入哪些内容,隐藏内部实现细节。
组织子包在包含子包的复杂项目中,每个子包目录都需要自己的 __init__.py 文件,以递归地标识整个层次化的包结构。
  1. 也就说Python程序 导入一个Python包的某个模块时,会先执行包的__init__.py程序,再执行导入的模块程序。
  2. 一个常用的__init__.py文件内容如下:
# __init__.py 文件示例

# 包版本信息
__version__ = "1.0.0"
__author__ = "Your Name"

# 导入包中的重要功能,方便用户使用
from .module1 import main_function
from .module2 import HelperClass

# 定义 __all__ 来控制 from package import * 的行为
__all__ = ['main_function', 'HelperClass', '__version__']

# 包初始化代码
print(f"初始化 {__name__} 包,版本 {__version__}")
  1. 包的导入和模块导入的用法一致
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐