一文搞懂如何自己写一个Python库
一文搞懂如何自己写一个Python库
你是否曾想过为自己的Python项目编写一个库,以便在不同项目中重复使用代码?
并且能在PyPI仓库中发布,并通过pip install 库名
来安装使用
编写Python库可能看起来有些复杂,但实际上并非如此。本文将为你提供一份简明的指南,带你逐步了解如何编写自己的Python库。
文章共分以下部分:
- 准备工作
- 创建项目
- 编写代码
- 添加库的文档和注释
- 测试你的库
- 发布到PyPI测试仓库
- 发布到PyPI官方仓库
- 通过pip安装测试使用
- 总结
一、准备工作
1.1 注册PyPI账号
在
https://test.pypi.org/
平台上自己注册一个账号,用于测试发布的库在
https://pypi.org/
平台上自己注册一个账号,用于正式发布库
1.2 为你的库取个好听的名字
在开始编写之前,你需要明确你的库将要实现的功能以及它的使用场景。并为你的库取一个好听好记的名字,这有助于确保你的库能够满足用户的需求,并且避免在后期频繁修改。
例如:我想实现一个自己常用库的封装,取名为yourtools
, 为什么不直接取tools
呢?因为有重名的库,所以大家取名的时候记得先去PyPI平台上搜索看看有没有重名的库。重名的话无法发布~
二、创建项目
准备工作完成后,接下来开始创建一个新的目录来作为你的库的项目文件夹。在这个目录中,你需要包含一个setup.py
文件来描述你的库,并且在适当的位置创建Python模块文件以及其他必要的文件。
├── yourtools 目录
│ └── db 目录
│ ├── __init__.py
│ └── mysql.py 工具类
├── requirements.txt 依赖库
├── setup.py 安装脚本
├── README.md 说明文档
├── upload_pypi.sh 上传到官方PyPI仓库脚本
├── upload_pypi_test.sh 上传到官方测试PyPI仓库脚本
这里我新建了以上文件目录,并对每个文件进行了解释。以上文件都空着即可,后续会详细讲解每个文件的代码
三、编写代码
开始编写你的Python代码,实现你所定义的功能。确保你的代码结构清晰,遵循Python的最佳实践和PEP规范。
本次演示我们将实现一个针对pymysql
通用的MySQL工具类
mysql.py
import pymysql
from sshtunnel import SSHTunnelForwarder
from .dbutils import DBConfig
class MySQL:
def __init__(self, db_config, ssh_tunnel=None):
self.dbconfig = DBConfig(db_config)
if ssh_tunnel:
ssh_tunnel.start()
self.dbconfig.host = ssh_tunnel.local_bind_host
self.dbconfig.port = ssh_tunnel.local_bind_port
self._init()
def _init(self):
try:
self.connect = pymysql.connect(
host=str(self.dbconfig.host),
port=self.dbconfig.port,
user=str(self.dbconfig.username),
passwd=str(self.dbconfig.password),
db=str(self.dbconfig.db),
charset=str(self.dbconfig.charset)
)
self.cursor = self.connect.cursor()
return True
except Exception as err:
raise Exception("MySQL Connection error", err)
return False
def get_conn(self):
if self.connect:
return self.connect
else:
self._init()
return self.connect
def close_conn(self):
if self.connect:
self.connect.close()
def query(self, sql, param=None):
"""
Query data
:param sql:
:param param:
:param size: Number of rows of data you want to return
:return:
"""
cur = self.connect.cursor(cursor=pymysql.cursors.DictCursor)
rows = None
try:
cur.execute(sql, param)
rows = cur.fetchall()
except Exception as e:
raise Exception(e)
self.connect.rollback()
cur.close()
return rows
def execute(self, sql):
"""
exec DML:INSERT、UPDATE、DELETE
:param sql: dml sql
:param param: string|list
:return: Number of rows affected
"""
try:
self.cursor.execute(sql)
self.connect.commit()
except Exception as e:
self.connect.rollback()
代码很简单,这里不再解释。
为了后续import方便,我们在__init__.py里对外部暴露的包名规范一下
# __init__.py
from .db.mysql import MySQL
四、添加库的文档和注释
良好的文档和注释对于一个库的成功至关重要。为你的代码添加详细的文档字符串和注释,以便其他人能够理解你的代码,并且能够方便地使用你的库。
接下来,我们编写README.md
,这个README.md
文件内容决定了你的库在PyPI平台展示的内容,例如:
五、测试你的库
库发布之前要进行自测,避免pip安装使用时有问题。可以直接在pycharm里测试使用,也可以外部调用测试,这里我们假设我们mysql.py
代码已经完成没问题。
六、发布到PyPI测试环境
一旦你确认你的库已经完善,你可以选择将其发布到PyPI等Python包管理器中,使其他人能够方便地安装和使用你的库。
编写发布库setup.py
文件
import setuptools
import re
import requests
from bs4 import BeautifulSoup
package_name = "yourtools"
def curr_version():
# 方法1:通过文件临时存储版本号
# with open('VERSION') as f:
# version_str = f.read()
# 方法2:从官网获取版本号
url = f"https://pypi.org/project/{package_name}/"
response = requests.get(url)
soup = BeautifulSoup(response.content, "html.parser")
latest_version = soup.select_one(".release__version").text.strip()
return str(latest_version)
def get_version():
# 从版本号字符串中提取三个数字并将它们转换为整数类型
match = re.search(r"(\d+)\.(\d+)\.(\d+)", curr_version())
major = int(match.group(1))
minor = int(match.group(2))
patch = int(match.group(3))
# 对三个数字进行加一操作
patch += 1
if patch > 9:
patch = 0
minor += 1
if minor > 9:
minor = 0
major += 1
new_version_str = f"{major}.{minor}.{patch}"
return new_version_str
def upload():
with open("README.md", "r") as fh:
long_description = fh.read()
with open('requirements.txt') as f:
required = f.read().splitlines()
setuptools.setup(
name=package_name,
version=get_version(),
author="Author's name", # 作者名称
author_email="xxxxxxx@163.com", # 作者邮箱
description="Python helper tools", # 库描述
long_description=long_description,
long_description_content_type="text/markdown",
url="https://pypi.org/project/yourtools/", # 库的官方地址
packages=setuptools.find_packages(),
data_files=["requirements.txt"], # yourtools库依赖的其他库
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires='>=3.6',
install_requires=required,
)
def write_now_version():
print("Current VERSION:", get_version())
with open("VERSION", "w") as version_f:
version_f.write(get_version())
def main():
try:
upload()
print("Upload success , Current VERSION:", curr_version())
except Exception as e:
raise Exception("Upload package error", e)
if __name__ == '__main__':
main()
upload_pypi_test.sh
为了保证库使用正常,我们建议先把库发布到PyPI的测试环境:https://test.pypi.org
,我们可以直接修改upload_pypi_test.sh
#!/bin/zsh
rm -rf ./build
rm -rf ./dist
rm -rf ./yourtools.egg-info
python3 setup.py sdist bdist_wheel
python3 -m twine upload --repository-url https://test.pypi.org/legacy/ dist/*
upload_pypi_test.sh代码编写完后,可以执行sh upload_pypi_test.sh
发布到测试环境,发布过程中,需要输入PyPI平台的用户名和密码
发布到测试环境后,可以直接通过pip命令安装pip install -i https://test.pypi.org/simple/yourtools
如果pip安装成功后,可以写一个test.py文件来测试使用,由于我们在__init__.py
里提前import了MySQL,所以这里我们只需要执行如下命令即可导入
from yourtools import MySQL
如果以上命令没报错,则说明库导入完成,下面可以测试数据库工具类的增删改查功能了
def test_mysql():
dbconfg = {
'host': '172.0.0.1',
'port': 3306,
'username': 'root',
'password': '123456',
'db': 'test',
'charset': 'utf8'
}
server = SSHTunnelForwarder(
('跳板机服务器IP', 45535),
ssh_username='root',
ssh_password='123456',
remote_bind_address=('远程数据库IP', 3366),
local_bind_address=('127.0.0.1', 3366)
)
# 不使用跳板机
mysql = MySQL(dbconfg)
# 使用跳板机,需要传递一个SSHTunnelForwarder对象
mysql = MySQL(dbconfg,ssh_tunnel=server)
# query data
result = mysql.query("select * from users")
print(result)
# dml sql
result = mysql.execute("insert into users(name,birthday,ts) values('灭霸2','2022-11-01 16:00:00','2022-11-01 16:00:00') ")
七、发布到PyPI官方仓库
如果以上测试没问题,下面我们将该库发布到PyPI的生产仓库中,同样逻辑,修改upload_pypi.sh
文件
#!/bin/bash
# Upload project to pypi
rm -rf ./build
rm -rf ./dist
rm -rf ./yourtools.egg-info
python3 setup.py sdist bdist_wheel
python3 -m twine upload dist/*
执行sh upload_pypi.sh
发布到PyPI生产环境,发布过程中,需要输入PyPI平台的用户名和密码
八、通过pip安装测试使用
当以上步骤全部完成后,恭喜你,已经实现了将自己写的Python发布到PyPI仓库中了,接下来就可以把这个牛逼轰轰的库告诉你身边的朋友推广使用了。
九、总结
- 本文基于
yourtools
库作为演示说明,该库地址https://pypi.org/project/yourtools/ - yourtools库源码:https://github.com/FearlessPeople/yourtools
- 小提示:通过
setup.py
文件,还可以将你的代码部署到私有Python解释器环境中哟,例如你公司服务器上的Python环境里
以上就是编写Python库的步骤,通过这些步骤,你也可以轻松地编写出一个Python库,为自己和其他人提供便利。祝你编写愉快!
关注公众号【大喇叭IT】,回复python
可进群沟通交流
一文搞懂如何自己写一个Python库的更多相关文章
- 一文搞懂 Promise 新 Api allSettled 的用法和 all 区别,以及如何在不支持新特性的环境下实现一个 Polyfill
开始 一文搞懂 Promise 新 Api allSettled 的用法和 all 区别,以及如何在不支持新特性的环境下实现一个 Polyfill allSettled 的用法 const runAl ...
- 一文搞懂RAM、ROM、SDRAM、DRAM、DDR、flash等存储介质
一文搞懂RAM.ROM.SDRAM.DRAM.DDR.flash等存储介质 存储介质基本分类:ROM和RAM RAM:随机访问存储器(Random Access Memory),易失性.是与CPU直接 ...
- 三文搞懂学会Docker容器技术(下)
接着上面一篇:三文搞懂学会Docker容器技术(上) 三文搞懂学会Docker容器技术(中) 7,Docker容器目录挂载 7.1 简介 容器目录挂载: 我们可以在创建容器的时候,将宿主机的目录与容器 ...
- 一文搞懂所有Java集合面试题
Java集合 刚刚经历过秋招,看了大量的面经,顺便将常见的Java集合常考知识点总结了一下,并根据被问到的频率大致做了一个标注.一颗星表示知识点需要了解,被问到的频率不高,面试时起码能说个差不多.两颗 ...
- 一文搞懂如何使用Node.js进行TCP网络通信
摘要: 网络是通信互联的基础,Node.js提供了net.http.dgram等模块,分别用来实现TCP.HTTP.UDP的通信,本文主要对使用Node.js的TCP通信部份进行实践记录. 本文分享自 ...
- 一文搞懂Google Navigation Component
一文搞懂Google Navigation Component 应用中的页面跳转是一个常规任务, Google官方提供的解决方案是Android Jetpack的Navigation componen ...
- 基础篇|一文搞懂RNN(循环神经网络)
基础篇|一文搞懂RNN(循环神经网络) https://mp.weixin.qq.com/s/va1gmavl2ZESgnM7biORQg 神经网络基础 神经网络可以当做是能够拟合任意函数的黑盒子,只 ...
- 一文搞懂 Prometheus 的直方图
原文链接:一文搞懂 Prometheus 的直方图 Prometheus 中提供了四种指标类型(参考:Prometheus 的指标类型),其中直方图(Histogram)和摘要(Summary)是最复 ...
- Web端即时通讯基础知识补课:一文搞懂跨域的所有问题!
本文原作者: Wizey,作者博客:http://wenshixin.gitee.io,即时通讯网收录时有改动,感谢原作者的无私分享. 1.引言 典型的Web端即时通讯技术应用场景,主要有以下两种形式 ...
- 一文搞懂vim复制粘贴
转载自本人独立博客https://liushiming.cn/2020/01/18/copy-and-paste-in-vim/ 概述 复制粘贴是文本编辑最常用的功能,但是在vim中复制粘贴还是有点麻 ...
随机推荐
- SqlSugar的查询函数SqlFunc
用法 我们可以使用SqlFunc这个类调用Sql函数,用法如下: db.Queryable<Student>().Where(it => SqlFunc.ToLower(it.Nam ...
- C# 中类与继承等概念
C#是一种现代的.面向对象的编程语言,其中类和继承是面向对象编程语言中非常重要的概念,类和继承是C#中面向对象编程的基本概念,可以用于创建复杂的应用程序和模块,而多态和接口可以使程序更加灵活和可扩展. ...
- SpringCloud之Ribbon负载均衡
上述案例中,我们启动了一个msg-service,然后通过DiscoveryClient来获取服务实例信息,然后获取ip和端口来访问. 但是实际环境中,我们往往会开启很多个user-service的集 ...
- MongoDB 7.0 搭建 Sharding 副本集群
本文是在ubuntu 22.03 系统版本上部署的,最低支持mongodb-6.0.4以上,所以这里安装mongodb7.0 1 安装mongo 安装方式有多种,本人是使用的第一种方式,时间也就20分 ...
- Windows7 SP1 安装.NET Framework4失败
系统版本是Windows7旗舰版,已经安装了SP1补丁,但还是无法安装.NET Framework4或者4.5,提示安装失败. 这时可以安装.NET Framework4.8的开发包,我这里安装开发包 ...
- 谁更适合搭配甜点显卡?i7-13700KF、锐龙7 7800X3D对比:游戏相当 生产力Intel强了50%
一.前言:如果搭配2000元甜点显卡 i7-13700KF和锐龙7 7800X3D谁更有性价比? 现在AMD最受欢迎的处理器无疑是拥有96MB三级缓存的锐龙7 7800X3D,这是一颗专为游戏而生的处 ...
- 吉特日化MES & WMS 与周边系统集成架构
作者:情缘 出处:http://www.cnblogs.com/qingyuan/ 关于作者:从事仓库,生产软件方面的开发,在项目管理以及企业经营方面寻求发展之路 版权声明:本文版权归作者和博客园 ...
- 使用vscode 用git 拉取代码,提示:在签出前,请清理存储库工作树
使用vscode 用git 拉取代码,提示:在签出前,请清理存储库工作树 如图: 问题: git仓库上的代码和本地代码存在冲突了所以会报这个报错. 解决办法: 手动解决①git stash 先将本地修 ...
- JS 可选链操作符?. 空值合并运算符?? 详解,更精简的安全取值与默认值设置小技巧
壹 ❀ 引 说来也比较惭愧,可选链操作符?.在公司项目中使用特别频繁,而我在之前一直以为是类似奇技淫巧的写法,所以也没去查阅相关文档,直到在学习typescript时碰巧看到了可选链操作符与空值合并操 ...
- android架构组件Lifecycle
Lifecycle 组件指的是 android.arch.lifecycle 包下提供的各种类与接口,可以让开发者构建能感知其他组件(主要指Activity .Fragment)生命周期(lifecy ...