Python项目结构和文件路径操作

Python 的项目结构从模块(.py) 到 包(Package) 再到 库(Library) 构成。对于模块导入,Python依赖于sys.path;而对于文件路径操作,则依赖工作目录CWD

  • sys.path: 包含了一系列字符串的路径,Python 会根据顺序,从这些目录中查找对应的模块,以下为示例:

    [
     '/home/user/project',            # [重点] 优先级最高:脚本所在目录
     '/usr/lib/python310.zip',        # 标准库压缩包
     '/usr/lib/python3.10',           # 标准库源码
     '/usr/lib/python3.10/lib-dynload', # C扩展模块
     '/home/user/project/venv/lib/python3.10/site-packages' # 第三方库(pip安装的)
    ]
    
  • 工作目录CWD
    例如:在路径/home/user/下有一个文件test.py

    1. 直接运行脚本

      python test.py
      

      此时,Python 会将 /home/user/ 加入到 sys.path 中,且通常 CWD 也是 /home/user/。

    2. 作为模块运行

      # 注意:这里不需要 .py 后缀
      python -m test
      

      这会将当前终端所在的目录加入 sys.path 并搜索名为 test 的模块运行。

项目结构

  • 模块Python中最简单的单位,是一个.py文件,该文件中可以包括类、函数、变量等。
  • 是一种特殊的文件目录,规范建议在包目录下生成__init__.py文件, 用于暴露包内的组件(子包、类、方法、变量等)并表示该目录是一个包。
  • 是一个宽泛的概念,指一个包或者多个包的集合,库可以被其他项目进行引入。

包和模块的导入

可以使用绝对路径或者相对路径进行包的导入,绝对路径不需要自己计算,但是文件迁移后需要及时更新,而相对路径导入则可以更方便的保留上下文关系。

其中相对路径可以用. 进行表示:

  • . 表示当前目录下:from .second import second_func 从同目录的second.py中引入second_func 函数
  • .. 表示上级目录(父包)
  • ... 表示上上级目录,以此类推。

路径需要遵守的基本规则

  • 只在包的内部使用相对导入,因为不用关心顶层名称
  • 在顶层的脚本避免使用子目录的细节
  • 合理利用__init__.py 来设计包的公共API,增强调用时的体验。
  • 永远从项目根目录启动应用。
  • 如果直接运行python module.py ,脚本内部的相对导入会失败,必须使用 python -m

路径

Python 提供了两种路径处理相关库: os.path 虽兼容 Python 2,但在现代开发中,强烈推荐使用 pathlib。它采用了面向对象的设计,语法更加优雅、直观。

在 Python 中可以通过 导入 pathlib 模块来查询当前的工作目录。

from pathlib import Path
print(Path.cwd())    # /home/user

拼接路径

pathlib提供了一种跨平台的方法来处理文件路径。通过 /运算符可以合并路径,pathlib会自动将其转换为操作系统的正确路径分隔符。例如:

from pathlib import Path

p = Path("/home/user") / "test.py"
print(p)    # /home/user/test.py

相对路径

在 Python中的相对路径是基于当前的工作目录(CWD)来决定的。与当前文件本身的路径无关,实际上是与CWD 组成了相对路径:

from pathlib import Path

if __name__ == '__main__':
    p = Path("test.py")
    if p.resolve() == Path.cwd() / "test.py":
        print("相等")

而获取文件自身的路径,然后再进行拼接,就可以形成真正的相对路径

from pathlib import Path

if __name__ == '__main__':
    # 1. 获取当前文件 (test.py) 的绝对路径
    current_file_path = Path(__file__).resolve()

    # 2. 获取当前文件所在的目录 (父级文件夹), 相当于该脚本的“基准目录”
    base_dir = current_file_path.parent

    # 3. 构建相对路径, 读取同级目录下 data 文件夹里的 config.json
    target_path = base_dir / "data" / "config.json"

    print(f"当前脚本路径: {current_file_path}")
    print(f"基准目录: {base_dir}")
    print(f"目标文件路径: {target_path}")

pathlib功能速查

1. 创建链接

  • Path.home():获取用户 Home 目录 (例如 C:\Users\Name 或 /home/name)
  • Path("data/logs/error.log"):通过字符串创建路径对象
  • Path("data", "logs", "error.log"): 通过各个部分组合创建对象 (自动适配OS)

2. 检查

  • Path.exists():检查路径是否存在。
  • Path.is_file():检查路径是否为文件。
  • Path.is_dir():检查路径是否为目录。
  • Path.parent:获取路径的父目录。

3. 获取路径属性

  • Path().name→ 完整文件名,例 photo.jpg
  • Path().stem→ 无后缀文件名,例 photo
  • Path().suffix→ 后缀,例 .jpg
  • Path().parts→ 分割后的元组,例 ('/', 'src', 'utils', 'helper.py')
  • Path().parent→ 所在目录

4. FileSystem 操作

  • Path(A).mkdir(parents=True, exist_ok=True) :创建文件夹A,已存在也不报错
  • Path(A).rename(Path(B)) :将A路径移动到B路径
  • Path(A).unlink(missing_ok=True) :删除路径A,不存在也不报错
  • Path(A).rmdir() :删除文件夹
  • Path(A).write_text()覆盖写文件,适用于简单情况
  • Path(A).read_text()全量读文件,适用于简单情况
  • Path(A).glob("*.py") :通配符查找路径A(不包含子目录)下面的.py文件
  • Path(A).rglob("*.py") :通配符查找路径A(以及子目录)下面的.py文件
  • Path(A).open(mode=rwab) :打开文件A,完全适配内置的open() 函数
posted @ 2025-11-21 10:45  听风讲故事~  阅读(15)  评论(0)    收藏  举报