将自己的工作,构建为python
的Package
并上传至PYPI,使得其他开发者可以通过pip
安装并使用。这是我一直想做的事情,最近我成功将微博数据采集项目封装并上传至PYPI。为使得后续维护工作顺利开展,并方便上传新的Package
,特此记录工作要点。
如何将项目组织成Package
最重要的两个点就是__init__.py
文件和相对引用
首先我展示目前的Package-dev
目录
D:PackageName_dev
│ .gitignore
│ LICENSE
│ list.txt
│ pyproject.toml
│ README.md
│
├─dist
│ EuclidSearchPackage-0.5.0-py3-none-any.whl
│ EuclidSearchPackage-0.5.0.tar.gz
│
└─src
├─EuclidSearchPackage
│ │ __init__.py
│ │
│ ├─Demo
│ │ │ WeiboClassV2.py
│ │ │ WeiboClassV3.py
│ │ │ __init__.py
│ │
│ ├─Utils
│ │ │ EuclidDataTools.py
│ │ │ EuclidDataTools_test.py
│ │ │ MongoClient.py
│ │ │ Set_header.py
│ │ │ Utils.py
│ │ │ __init__.py
│ │
│ ├─WeiboSearch
│ │ │ Get_item_url_list.py
│ │ │ Get_longTextContent.py
│ │ │ Get_single_weibo_data.py
│ │ │ Get_single_weibo_data_async.py
│ │ │ Get_single_weibo_details.py
│ │ │ Get_user_all_weibo.py
│ │ │ Get_user_info.py
│ │ │ Set_cookie.py
│ │ │ __init__.py
│ │
│
├─EuclidSearchPackage.egg-info
│ dependency_links.txt
│ PKG-INFO
│ SOURCES.txt
│ top_level.txt
│
└─Test
│ cookie.txt
│ DemoTest.py
│ test.csv
│ Test.py
│ WeiboClassV2.py
一级目录说明
可以看到dev
一级路径下有
-
src
: 开发代码将写在这个文件夹下,后一节将展开讲解 -
dist
:当package
被正式build
时,该目录被自动创建,并生成whl文件在此目录下 -
pyproject.toml
:软件包架构参数设定,建议按照官方建议撰写 -
README.md
:说明文档,将同步到PYPI的项目介绍中,例如project description -
LICENSE
:版权信息,可以按照网上的教程选择 -
.gitignore
:git
控制中的ignore
,如果不使用git可以忽略
scr
说明
src
下有三个文件夹
EuclidSearchPackage
:包里面的程序,当包发布后,包的内容就是此文件夹中的文件EuclidSearchPackage.egg-info
:当package
被正式build
时,该目录被自动创建,将存储info
Test
:非必须,可以用于模拟package
被安装后的调用过程,作为测试
关于__init__.py
我们提取package的部分来看,如何写__init__.py
├─Demo
│ │ WeiboClassV2.py
│ │ WeiboClassV3.py
│ │ __init__.py
这是package中的一个subpackage
,名字为demo
,下有三个文件,其中WeiboClassV2.py
和WeiboClassV3.py
是代码,__init__.py
的内容为:
from .WeiboClassV2 import WeiboClassV2
from .WeiboClassV3 import WeiboClassV3
简单来说init
的作用就是初始化,在调用时,init
会被首先执行,将WeiboClassV2
和WeiboClassV3
调入代码空间,使其可以被调用。需要注意的是相对位置的引用规则,即得加一个.
下面展示一个完整的__init__.py
,变量__all__
展示了,使用import *
能被调用的方法或变量
from .Get_item_url_list import Get_item_url_list
from .Get_user_info import Get_user_info
from .Set_cookie import Set_cookie
from .Get_single_weibo_data import Get_single_weibo_data
from .Get_user_all_weibo import Get_user_all_weibo
from .Get_single_weibo_data_async import Get_single_weibo_data_async
from .Get_longTextContent import Get_longTextContent
# 未完成
from .Get_single_weibo_details import Get_single_weibo_details
__all__ = ['Get_user_all_weibo', 'Get_user_info', 'Set_cookie',
'Get_item_url_list', 'Get_single_weibo_data',
关于相对位置引用
在上一节的init
写法中已经讲到了得加.
,但是有一种情况是需要另外注意的,提取目录的部分进行说明:
├─Utils
│ │ MongoClient.py
│ │ Set_header.py
│ │ __init__.py
├─WeiboSearch
│ │ Get_item_url_list.py
具体场景为,在Get_item_url_list.py
中需要调用Set_header.py
中的Set_header
函数,那么需要
-
首先确保
__init__.py
中from .Set_header import Set_header from .Set_header import * # 二选一,更推荐上面的写法
-
在
Get_item_url_list.py
中,使用如下方式引用Set_header
函数from ..Utils import Set_header
关于Test
目录
此目录可以模拟包被安装后的使用过程,不过导入还是有些微差别,需要加上src.
:
import src.EuclidSearchPackage as ESP
后续的写法就完全一致了,建议发布前都测试一下。
打包发布Package
建议参照官方教程,总结起来有这么关键的几步:
Creating pyproject.toml
,即软件包架构参数设定,建议按照官方建议撰写Creating README.md
:代码说明,建议还是写清楚,会同步到PYPI的project description- Creating a LICENSE:官方的示例
build
:构建包python -m build
,生成的文件会在dist
目录下,版本迭代后,记得删掉旧版本upload
:将package
上传至PYPI
,python twine upload dist/*
,需要输入用户名和密码,如果没有账号需要提前创建。
更新维护
建议同步将package_dev
开源至github
,方便接受issue
,对package
更新后,记得更新版本号,然后重新build上传就好。
- python_Package Package pythonpython_package python_package package python relative package python import neopixel package python bugs development project package python package python create how directory pycharm package python 服务器package python ubutn timezone package python all 名称package python class