Python 制作自定义库实践

版本基于:Python 3.12

0. 前言

随着工具开发的功能日益强大,模块化已经是大势所趋,所以,需要将整个工具项目的公共部分提取并制作为自定义的库。网上很多优秀的文章可以参考,作为小白的笔者结合了自己的实践经验,做一个小结,利己利人~~

1. 前提

保证  python 的正确安装。笔者在制作自定义库,一直出现:

PS C:\Users\justin.wei> parse.py
Traceback (most recent call last):
  File "D:\work\mydoc\parse_meminfo\parse.py", line 5, in <module>
    from perftools.mem_parser    import ParseTneLog, ParseDBLog
ModuleNotFoundError: No module named 'perftools'

但实际上 pip list 确实是存在的,pip show perftools 也能正确显示:

PS C:\Users\justin.wei> pip show perftools
Name: perftools
Version: 2.0
Summary: Performance tools
Home-page:
Author: Justin Wei
Author-email: justinwei.wj@gmail.com
License:
Location: C:\Users\justin.wei\AppData\Roaming\Python\Python312\site-packages
Requires: pandas
Required-by:

务必保证 python 环境的干净!!!

打开 “设置” --> “应用” 将所有的 python 程序都卸载掉,如果通过 Microsoft Store 已经安装了python 程序,系统将会以该程序优先执行,环境变量也优先适配该程序。

如果同时手动下载 exe 安装的python,无论如何配置环境变量,都将无法生效。

2. 准备源码

|----mylib
     |----perftools
     |    |----base
     |    |    |----__init__.py
     |    |    |----android.py
     |    |    |----utils.py
     |    |----config
     |    |    |----peretto_cfg.pbtx
     |    |    |----configs.json
     |    |----__init__.py
     |    |----mem_parser.py
     |    |----mem_analyzer.py
     |    |----perfetto.py
     |----setup.py
     |----install.bat
     |----MANIFEST.in

代码的层级很重要,其中:

  • 根目录可以是任务的名称,里面包含三个文件:
    • 库名称的文件夹;
    • setup.py 文件;
    • MANIFEST.in 文件;
  • 库文件夹中包含:
    • __init__.py 文件,用以标记其所在的目录是一个package;
    • 源码的 py 文件

注意:

__init__.py 和 setup.py 的名称和层级不能弄错,否则即使后面 pip install 成功,在使用时也无法找到该库。

3. __init__.py 文件

__init__.py 文件在 Python 中有特殊的含义。它的存在标志着其所在的目录是一个 Python 包,这样它就可以被其他脚本导入。

以下是 __init__.py 文件的主要用途:

  • 包的初始化:当导入一个包时,Python 会自动执行 __init__.py 文件中的所有顶级代码。你可以在这个文件中执行所有需要在包初始化时进行的操作。
  • 控制导入:你可以在 __init__.py 文件中定义一个名为 __all__ 的列表,来指定当用户使用 from package import * 语句时,应该导入哪些模块。
  • 简化导入:如果你的包的结构很深,__init__.py 文件可以用来方便地导入深层模块。例如,在 __init__.py 文件中导入深层模块,用户就可以直接通过 import package.module 的方式导入,而不需要 import package.subpackage.module
  • 包的文档字符串__init__.py 文件的文档字符串通常用作包的文档,help() 函数会显示它。

注意,从 Python 3.3 开始,__init__.py 文件不再是必需的,Python 3.3 引入了隐式的命名空间包,这允许你创建包而无需 __init__.py 文件。然而,如果你需要执行特定的包初始化代码,或者需要使用上述提到的 __all__ 变量,你仍然需要 __init__.py 文件。

更多可以查看:The '__init__.py' File: What Is It? How to Use It? (Complete Guide)

4. setup.py 文件

setup.py 是 Python 库的构建脚本,它是 Python 的标准库 setuptools 的一部分。这个文件用于定义库的元数据,如名称、版本、作者、许可证等,以及库的依赖关系和打包设置。

以下是 setup.py 文件的基本结构:

from setuptools import setup, find_packages

setup(
    name='your-package-name',
    version='0.1.0',
    author='Your Name',
    author_email='your.email@example.com',
    description='A short description of your project',
    long_description=open('README.md').read(),
    long_description_content_type='text/markdown',
    url='https://github.com/yourusername/your-package-name',
    packages=find_packages(),
    classifiers=[
        'Programming Language :: Python :: 3',
        'License :: OSI Approved :: MIT License',
    ],
    install_requires=[
        'numpy',
        'pandas',
        # other libraries your project depends on
    ],
)
  • name 是你的包的名称。
  • version 是你的包的版本号。
  • author 和 author_email 是你的名字和电子邮件地址。
  • description 是你的项目的简短描述。
  • long_description 是你的项目的长描述,通常从 README 文件中读取。
  • long_description_content_type 指定长描述的格式,通常是 ‘text/markdown’ 或 ‘text/rst’。
  • url 是你的项目的主页,通常是 GitHub 仓库的 URL。
  • packages 是你的包中的模块,find_packages() 函数会自动找到它们。
  • classifiers 是一组标记,用于描述你的项目,如支持的 Python 版本、许可证等。
  • install_requires 是你的项目的依赖列表,setuptools 会在安装你的包时自动安装这些依赖。

当你运行 python setup.py install 命令时,setuptools 会读取 setup.py 文件,然后编译、构建和安装你的包。你也可以使用 python setup.py sdist bdist_wheel 命令来创建源代码分发和二进制分发,这些分发可以上传到 PyPI,让其他人通过 pip install 命令安装你的包。

更多 setup.py

5. MANIFEST.in

除了python 的文件以外,有可能还需要在编译的时候携带其他类型的文件,例如config 等配置文件。通过 MANIFEST.in 文件实现这个功能,代码结构如第 1节。

前提条件,需要在 setup.py 中添加:

include_package_data=True
命令说明
include pat1 pat2 ...包含指定 pattern 的文件,文件需要指定相对路径
exclude pat1 pat2 ...与include 相反,移除这些pattern 的文件
recursive-include dir-pattern pat1 pat2 ...在指定的目录下,递归地包含指定 pattern 的文件
recursive-exclude dir-pattern pat1 pat2 ...与include 相反,递归地移除这些pattern 的文件
global-include pat1 pat2 ...包含所有指定pattern 的文件,不限制目录
global-exclude pat1 pat2 ...与include 相反,排除这些pattern 的文件
graft dir-pattern包含所有指定 dir-pattern 的目录
prune dir-pattern与 graft 相反,排除所有指定 dir-pattern 的目录

更多 MANIFEST.in

例如:

graft tests
global-exclude *.py[cod]

该 MANIFEST.in 中包含两条指令:

  • 添加当前目录树中 tests 目录到 sdist 目录树中;
  • 接着移除 sdist 中所有后缀包含 .pyc .pyo .pyc .pyo的文件。

6. 安装

cmd 到setup.py 所在的目录,运行命令:

pip install .

在第一节的目录结构中有个install.bat,可以自动安装:

for /d %%i in (*.egg-info) do (
	if exist "%%i" (
		rd /s /q "%%i"
	)
)

if exist build (
	rd /s /q build
)

pip install .

pause

7. 上传PyPI

全称 Python Package Index,它是 Python 的包管理系统。用户可以通过 PyPI 下载和安装 Python 包,也可以将自己开发的包上传到 PyPI,供其他人使用。

更多可以参考:https://zhuanlan.zhihu.com/p/60836179

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

私房菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值