Python进阶(4) | 创建Python库的模板工程 Python-lib-starter

news2024/11/17 3:27:41

Python进阶(4) | 创建Python库的模板工程 Python-lib-starter

文章目录

  • Python进阶(4) | 创建Python库的模板工程 Python-lib-starter
    • 1. 目的
    • 2. Python-lib-starter 目录结构浅析
      • 2.1 关键目录和文件
      • 2.2 非关键目录和文件
    • 3. moelib 目录分析
      • 3.1 `__init__.py`
        • 延迟评估类型注解的意义
        • 使用 from __future__ import annotations
        • 设置 `__version__` 等
      • 3.2 `__main__.py`
    • 4. tests 目录
      • 4.1 `__init__.py`
      • 4.2 `test_moelib.py`
  • This can be replaced with tomllib if you are using Python 3.11+
    • 5. 简化的代码

1. 目的

当我们使用 Python 写一些复用性较高的代码时候, 我们可以制作一个 Python 库, 用 pip install 的方式提供下载。

像 PyTorch, OpenCV 或 Pillow 这些工程, 都过于复杂庞大。 是否有一个“空壳”的 Python 工程, 它已经是一个 Python 包、 只需要我们填充核心功能代码呢? python-lib-starter (https://github.com/ShigureLab/python-lib-starter) 就是这样一个项目。

在这里插入图片描述

2. Python-lib-starter 目录结构浅析

git clone https://github.com/ShigureLab/python-lib-starter
cd python-lib-starter
code .

在这里插入图片描述

2.1 关键目录和文件

可以看到关键目录有两个:

  • moelib: 库的核心代码
  • tests: 库的单元测试代码

关键文件只有一个:

  • setup.py: 配置了安装功能

2.2 非关键目录和文件

非关键目录:

  • .github: CI/CD 脚本
  • .vscode: VSCode 配置和扩展

非关键文件:

  • .editorconfig: 代码风格配置文件
  • .gitignore: git 忽略文件
  • .prettierignore: 代码格式化工具 Pretty 的配置文件。js文件使用的。
  • .prettierrc: 配置 Prettier 代码格式化工具的选项和规则的。个人觉得比较冗余,有了 .editorconfig 基本够用
  • justfile: justfile 是 Just 命令运行器的配置文件,用于定义一组命令和指令,这些命令和指令可以通过 Just 工具来执行。Just 是一个命令行工具,旨在使运行项目中的特定任务(如构建、测试、部署等)变得简单快捷。它类似于 Makefile 用于 make 命令,但 Just 提供了更现代和更易于使用的语法。
  • poetry.lock: poetry.lock 文件是由 Poetry 依赖管理工具生成的一个锁文件,用于确保项目依赖的一致性。Poetry 是一个现代的 Python 包管理工具,它旨在简化包的安装、版本管理和打包过程。当你使用 Poetry 添加、更新或安装项目依赖时,Poetry 会创建或更新 poetry.lock 文件。
  • poetry.toml: 不知道。
  • pyproject.toml: pyproject.toml 文件是一个用于配置和管理 Python 项目的文件,它遵循 TOML(Tom’s Obvious, Minimal Language)格式。这个文件的引入旨在提供一个统一的配置文件来替代之前分散在多个文件(如 setup.py、requirements.txt、setup.cfg 等)中的配置信息。pyproject.toml 文件的规范由 PEP 518 首次引入,并在后续的提案中得到扩展,比如 PEP 621 规定了项目元数据的标准。

总的来说, 这些非关键目录和文件是锦上添花, 关键目录和文件中, 其实有了单元测试, 已经超过60分了, 在项目开发初期足够了。

3. moelib 目录分析

目录结构:

- moelib
    - `__init__.py`
    - `__main__.py`

3.1 __init__.py

# Meta information for the project.
from __future__ import annotations

__version__ = "0.1.3"
__author__ = "Nyakku Shigure"
__year__ = "2023"
__project_info__ = {
    "name": __name__,
    "version": __version__,
    "copyright": f"{__year__}, {__author__}",
    "author": __author__,
}

annotations 是“延迟评估类型注解”, 是 Python 3.10 中的默认行为, 3.10 版本之前只能在 __future__ 里获取。

延迟评估类型注解的意义

在 Python 3.7 之前,类型注解(Type Hints)在定义时就会被评估。这意味着,如果你在类型注解中引用了尚未定义的类或自身类(用于表示类方法的返回值是其实例),就会导致 NameError 或者其他错误。

例如,考虑下面的代码:

class Node:
    def add_child(self) -> Node:  # 这里使用 Node 作为返回类型
        pass

在 Python 3.7 之前,这段代码会引发错误,因为在 add_child 方法的注解中使用了 Node 类型,而在解释这行代码时 Node 类还没有完全定义。

使用 from future import annotations

通过使用 from future import annotations,所有的类型注解都会被自动视为字符串字面量。这样,它们就不会在定义时立即被评估,而是延迟到实际需要进行类型检查的时候(比如使用类型检查工具如 MyPy 进行静态类型检查时)。这解决了上面提到的问题,允许你自由地在类型注解中引用尚未定义的类或自身类。

from __future__ import annotations

class Node:
    def add_child(self) -> Node:  # 现在这样写不会引发错误
        pass

总的来说,from __future__ import annotations 让你能够在 Python 代码中更灵活地使用类型注解,尤其是在处理复杂的类型定义和类的相互引用时。这个特性在 Python 3.10 及以后的版本中成为了默认行为,所以如果你使用的是 Python 3.10 或更高版本,就不需要再显式地导入这个特性了。

设置 __version__

语句 __version__ = "0.1.3" 的含义是将字符串 “0.1.3” 赋值给名为 version 的全局变量。这个字符串通常遵循语义化版本控制(Semantic Versioning),其中:

  • 0 表示主版本号(Major version),当你做了不兼容的 API 修改时,需要增加这个数字。
  • 1 表示次版本号(Minor version),当你以向下兼容的方式添加功能时,增加这个数字。
  • 3 表示修订号(Patch version),当你做向下兼容的问题修正时,增加这个数字。
__project_info__ = {
    "name": __name__,
    "version": __version__,
    "copyright": f"{__year__}, {__author__}",
    "author": __author__,
}

__project_info__ 是一个自定义的字典,用于存储关于项目的信息。这种做法并不常见,但它展示了如何在一个地方集中管理项目的元数据,包括项目名、版本、版权信息和作者信息。这些信息可以在项目的多个地方被引用或展示,比如在文档、项目首页或者版权声明中

3.2 __main__.py

from __future__ import annotations

import argparse

from moelib import __version__


def main() -> None:
    parser = argparse.ArgumentParser(prog="moelib", description="A moe moe project")
    parser.add_argument("-v", "--version", action="version", version=__version__)
    args = parser.parse_args()  # type: ignore


if __name__ == "__main__":
    main()

from future import annotations

同前一节, 导入 “延迟评估类型注解”。

import argparse

导入参数解析库。

from moelib import version

导入自己写的 moelib 库里面的 __version__ 变量。

def main() -> None:
    parser = argparse.ArgumentParser(prog="moelib", description="A moe moe project")
    parser.add_argument("-v", "--version", action="version", version=__version__)
    args = parser.parse_args()  # type: ignore

设置命令行参数, 可以用 python -m moelib -v 来执行,获取到版本好:

PS D:\github\python-lib-starter> pip install -e .
PS D:\github\python-lib-starter\moelib> python -m moelib -v
0.1.3

4. tests 目录

目录结构:

- tests
    - `__init__.py`
    - `test_moelib.py`

4.1 __init__.py

这个文件是空的。

4.2 test_moelib.py

通常单元测试文件的命名, 要么是 test 开头, 要么是 _test.py 结尾。

from __future__ import annotations

from pathlib import Path

# This can be replaced with tomllib if you are using Python 3.11+
import tomli as tomllib

from moelib import __version__

with Path("pyproject.toml").open("rb") as f:
    project_info = tomllib.load(f)


def test_version():
    assert __version__ == project_info["tool"]["poetry"]["version"]

我们主句分析:

from future import annotations

同前一节, 导入 “延迟评估类型注解”。

from pathlib import Path

导入 pathlib 库, 用于路径相关的操作。

This can be replaced with tomllib if you are using Python 3.11+

import tomli as tomllib

导入 tomlib, 用于解析 pyproject.toml 文件。

from moelib import version

从我们自己写的 moelib 库导入 __version__ 变量。

with Path(“pyproject.toml”).open(“rb”) as f:
project_info = tomllib.load(f)

用 tomllib 解析 pyproject.toml 的内容。

def test_version():
assert version == project_info[“tool”][“poetry”][“version”]

创建了一个单元测试的测试用例, 检查 __version__ 是否和 pyproject.toml 里的版本号一样。

个人觉得这个测试能体现一部分水平(了解单元测试),但是把版本号分散在两个地方(moelib/__init__.pypyproject.toml)无疑增加了维护的复杂性,其实没必要。实际上只要检查 __version__ 包含三个字段,每个字段都是数字,就可以了:

def test_version():
    #assert __version__ == project_info["tool"]["poetry"]["version"]
    # check if __version__ is semver
    assert __version__.count(".") == 2
    # each part of semver must be integer
    assert all(map(lambda x: x.isdigit(), __version__.split(".")))

5. 简化的代码

https://github.com/zchrissirhcz/python-lib-starter

去掉了 “不重要的代码”, 修改了单元测试, 适合项目最初开发时的本地开发。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1419876.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

flink cdc,standalone模式下,任务运行一段时间taskmanager挂掉

在使用flink cdc,配置任务运行,过了几天后,任务无故取消,超时,导致taskmanager挂掉,相关异常如下: 异常1: did not react to cancelling signal interrupting; it is stuck for 30 s…

最新详细eclipse下载、安装、汉化教程

一、下载eclipse安装包 首先进入 eclipse官网 如下: 这里面有很多版本;我们小白一般选择第二个,向下滑动; 点击符合自己系统的版本。 这里我们切换镜像下载,一般选择离你最近的地址下载。 我建议选择大连东软信息学…

Python 数据分析实战——社交游戏的用户流失?酒卷隆治_案例2

# 什么样的顾客会选择离开 # 数据集 DAU : 每天至少来访问一次的用户数据 数据内容 数据类型 字段名 访问时间 string(字符串) log_data 应用名称 string(字符串) app_name 用户 ID int(数值) user_id…

项目经理,如何管理好自己的情绪?

在现代社会中,压力无处不在。对于项目经理来说,压力更是来自各个方面,如项目进度、团队管理、客户需求等。当压力过大时,情绪就容易受到影响,如果无法控制自己的情绪,不仅会影响自己的工作效率,…

uniapp对接微信APP支付返回requestPayment:fail [payment微信:-1]General errors错误-全网总结详解

一、问题描述 uniapp对接微信APP支付,本来是很简单的一件事,后端本来就是好的,只要填一些参数就行了,搞了我一晚上,主要卡在uniapp这边,拉起支付的时候,一直提示以下错误: {"er…

Celery基础用法

Celery概述 Celery是一个分布式任务调度模块,用于在Python中处理异步任务。它允许你创建任务,并发送给工作节点执行。 Celery常常用于我们说的脏活,累活,处理耗时的操作,如发送电子邮件、处理数据、执行计算等。 上手非…

pytorch安装教程(Anaconda + GPU)

可以去nvidia官网更新驱动 获取下载pytorch的命令地址:Start Locally | PyTorch 在这里可以找到旧版本的cuda的命令:Previous PyTorch Versions | PyTorch 如果使用conda没有安装成功的话,就使用pip:

pytorch 实现中文文本分类

🍨 本文为[🔗365天深度学习训练营学习记录博客🍦 参考文章:365天深度学习训练营🍖 原作者:[K同学啊 | 接辅导、项目定制]\n🚀 文章来源:[K同学的学习圈子](https://www.yuque.com/mi…

故障诊断 | 一文解决,CNN卷积神经网络故障诊断(Matlab)

文章目录 效果一览文章概述专栏介绍源码设计参考资料效果一览 文章概述 故障诊断 | 一文解决,CNN卷积神经网络故障诊断(Matlab) 专栏介绍 订阅【故障诊断】专栏,不定期更新机器学习和深度学习在故障诊断中的应用;订阅

自然语言nlp学习 三

4-8 Prompt-Learning--应用_哔哩哔哩_bilibili Prompt Learning(提示学习)是近年来在自然语言处理领域中,特别是在预训练-微调范式下的一个热门研究方向。它主要与大规模预训练模型如GPT系列、BERT等的应用密切相关。 在传统的微调过程中&a…

【C++】Vulkan:计算机图形学Vulkan基础与环境配置

😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍计算机图形学Vulkan基础与环境配置。 无专精则不能成,无涉猎则不能通。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下&a…

pve web无法访问

一、问题描述 我这边修改了网络,导致ip发生了变更,pve网页版直接登不上了,ssh又可以登录。 二、解决方法 首先确认是不是网络的问题,我这边是内网,有多个路由器,笔记本连的是一个网段,pve又是一个网段,通过ping&…

Unity打包Android,jar文件无法解析的问题

Unity打包Android,jar无法解析的问题 介绍解决方案总结 介绍 最近在接入语音的SDK时,发现的这个问题. 当我默认导入这个插件的时候,插件内部的文件夹(我下面话红框的文件夹)名字原本为GCloudVoice,这时候我…

Spring Boot导出EXCEL 文件

主要功能:实现java导出excel到本地 JDK版本&#xff1a;openJDK 20.0.1 依赖pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchem…

Java / Spring Boot + POI 给 Word 添加水印

1、前言(瞎扯) 有个需求&#xff1a;整一个给 Word 加水印的demo&#xff0c;于是我就网上找呗~ 看到那个 Aspose 好像是收费的&#xff0c;然后就把目光转向了 POI&#xff0c;看到各种形形色色的也不知道哪个能用。整了一会&#xff0c;自己拷贝出一个比较精简的能用的 demo …

Ubuntu搭建国标平台wvp-GB28181-pro

目录 简介安装和编译1.查看操作系统信息2.安装最新版的nodejs3.安装java环境4.安装mysql5.安装redis6.安装编译器7.安装cmake8.安装依赖库9.编译ZLMediaKit9.1.编译结果说明 10.编译wvp-GB28181-pro10.1.编译结果说明 配置1.WVP-PRO配置文件1.1.Mysql数据库配置1.2.REDIS数据库…

封装通用mixins,在vue中实现a-table组件的可伸缩列(详细且使用便捷)

1、实现效果 2、使用场景 vue2 antd-vue 1.x版本由于antd-vue 1.x版本的组件库没有提供可伸缩列的功能&#xff0c;才需要我们手动开发在antd-vue 3.x版本以上的表格已经支持这个功能&#xff0c;不需要我们再去手动开发 3、话不多说&#xff0c;上代码 首先安装vue-dragga…

Android MediaCodec 简明教程(四):使用 MediaCodec 将视频解码到 Surface,并使用 SurfaceView 播放视频

系列文章目录 Android MediaCodec 简明教程&#xff08;一&#xff09;&#xff1a;使用 MediaCodecList 查询 Codec 信息&#xff0c;并创建 MediaCodec 编解码器Android MediaCodec 简明教程&#xff08;二&#xff09;&#xff1a;使用 MediaCodecInfo.CodecCapabilities 查…

白嫖!平替ChatGPT,高效阅读文档,支持pdf上传!

大家好&#xff0c;我是阿潘&#xff0c;现在技术更新的太快了&#xff0c;每天arxiv上面更新的论文太多了看不过来&#xff0c;同时还有一大堆公众号、知识星球、知乎等等&#xff0c;太多需要关注的信息了&#xff0c;力不从心啊。但是又怕漏掉一些有用的信息 因此今天跟大家…

FastBee开源物联网平台2.0开源版发布啦!!!

一、项目介绍 物美智能(wumei-smart)更名为蜂信物联(FastBee)。 FastBee开源物联网平台&#xff0c;简单易用&#xff0c;更适合中小企业和个人学习使用。适用于智能家居、智慧办公、智慧社区、农业监测、水利监测、工业控制等。 系统后端采用Spring boot&#xff1b;前端采用…