python学习---如何构建自己python包并且上传到pypi上,而且还能用pip安装?

我在自己打包python文件以及上传到pypi上的过程中遇到了很多问题,找了很多博客,但是没有找到适合我的,总是会出现各种问题,所以我打算自己写个博客来记录一下成功打包并且上传到pypi的过程。本文主要讲解如何创建自己的python包并且上传到pypi以便能够方便pip install, 便于代码的封装和泛用,在windows下成功构建,各位看官按需使用。


0.1 文件目录架构

首先确定你要打包的文件,例如我要打包的是一个叫做learnkeyhole的包,那么它的文件结构为:

├──learnkeyhole
│   ├──learnkeyhole
│       ├── nets
│       ├── utils
│       ├── __init__.py
│       ├── __main__.py
│       ├── .gitignore
│       ├── miou.py
│       ├── ....
│       ├── window.ui
│   ├──README.md
│   ├──requirements.txt
│   ├──setup.cfg
│   ├──setup.py
│   ├──LICENSE

我的文件实际架构为

目录

其中和以上代码里面不同的dist,build,.egg.info文件是经过打包以后生成的,将在后面详解setup时提到。

0.1.1 创建包文件

按照上述文件目录架构创建各个文件,其中README.mdLICENSE参考自己的需求填写即可。

LICENSE文件编写

我使用MIT格式的LICENSE,按照这个格式粘贴到LICENSE里面即可。

MIT License

Copyright (c) 2023 My_name

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so. 

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md文件编写

主要讲解一下自己的包的功能和使用方法,为了能够使该文件能够在pypi上显示(pypi支持rst文件显示),之后会在setup.py中说明。

必须包含的文件

__init__.py:我要打包的文件在learnkeyhole中,为了setuptools能够将文件夹识别为python包,必须要创建__init__.py,内容为空。

同时我这里在learnkeyhole下面还有子文件夹,其中的netsutils中也需要创建__init__.py以便能够在之后的打包中包括进去。

.gitignore:这个文件需要在打包时忽略某些文件,例如打包时忽略__pycache__/这个文件夹。

.idea/ 
__pycache__/

0.1.2 setup.py和setup.cfg创建

首先确认自己的环境中已经安装了setuptoolsdistutils

setup.cfg提供一种方式,可以让包的开发者提供命令的默认选项,同时为用户提供修改的机会。对setup.cfg的解析,是在setup.py之后,在命令行执行前。

setup.py中具体描述构建包的各种参数,其中setup.py中的参数可以对setup.cfg中的参数进行覆盖。

cfg的格式

以下是cfg的格式内容,按照注释进行自己的更改

[metadata]
name=learnkeyhole        #your package name
version=your_version
author=your_name
author_email=your_email
description=Use this package to train your keyhole and predict it rapidly and right
license=MIT
url= https://github.com/wu-xz21/learnkeyhole  #github地址或其他地址,这个地址随便填写就行,主要要能访问就行,最好是你的repository地址。
classifiers=
    Environment :: Web Environment
    Intended Audience :: Developers
    License :: OSI Approved :: MIT License
    #Natural Language :: Chinese        #我这里把它注释掉了,因为之后构建的时候报错了,不知道为甚,不过没关系,注释掉没有影响
    Operating System :: MacOS
    Operating System :: Microsoft
    Operating System :: POSIX
    Operating System :: Unix
    # Topic :: NLP                  #我这里把它注释掉了,因为之后构建的时候报错了,不知道为甚,不过没关系,注释掉没有影响
    Topic :: Software Development :: Libraries :: Python Modules
    Programming Language :: Python :: 3.6       #python版本
    Programming Language :: Python :: 3.8
    

[options]
zip_safe=True
packages=find_packages()        #这里find_package最好这样写,另外的写法可能会报错
include_package_data=True       #重要
python_requires= >=3.6,<=3.9    #对于python版本的要求,
install_requires=               #python包需要的依赖,根据自己的项目而定
    pandas>=1.5.0
    numpy>=1.20.2
    scipy>=1.9.0
    matplotlib>=3.5.0
    opencv_python>=4.4.0.40
    torch>=1.7.1
    torchvision>=0.8.2
    tqdm>=4.55.0
    pillow>=8.2.0
    h5py>=3.6.0
    PyQt5>=5.14.0

以上内容中install_requires参数为包运行所需要的环境,内容同requiresments.txt中的内容相同。

其中,依赖最好通过>=指定,直接用==指定的话可能因为本身pip的版本未更新导致后续找不到版本,并且可以的话不要使用最新版本,有可能pip install 找不到。

name,version, author,author_email等内容均需自己指定,注意每次上传新的包到pypi时version都需要往上更改版本,否则会因为版本冲突报错,导致上传失败。

setup.py的格式

下面是setup.py的格式

from __future__ import print_function       #这个import必须放在第一行
import distutils.spawn
import sys

from setuptools import setup, find_packages

# 读取你的README.md文件以便能够在pypi中显示
from os import path
this_directory = path.abspath(path.dirname(__file__))
with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f:
    long_description = f.read()


setup(
    packages=find_packages(),

        package_data = {
        # 如果包中含有.txt文件,则包含它,我这里还有一个ui文件,那么也要包含。
        '': ['*.txt'],
        '': ['*.ui'],
        },
    include_package_data=True,      #这个一定要设置为True
    entry_points={
        'console_scripts':[
            'learnkeyhole = learnkeyhole.__main__:main'
        ]
    },
    long_description=long_description,          #这里的long_description结合上面的读取README.md
    long_description_content_type='text/markdown'       #long_descriptionde的类型
    
      )

要想自己写的README.md能在pypi上显示,需要导入并且设置编码格式utf-8,在setup的参数中填入long_description中。

为了包含非py文件,需要使用package_data参数,例如我的包中还有ui文件,需要设置'':['*.ui']来包含进来。

entry_points参数设置了在命令行中输入包的名字之后的指令。
例如我的主要程序功能在__main__.py中,因此,当我在命令行输入learnkeyhole时,根据'learnkeyhole = learnkeyhole.__main__:main'这条代码,__main__.py中的main函数将会被执行。

0.2 打包

通过以上操作,我们的包文件已经成功构建,之后就是快乐的打包。

运行cmd,转到setup.py所在的文件夹,运行命令

python setup.py sdist
python setup.py sdist bdist_wheel

在这里插入图片描述

其中,第一条在dist文件夹里生成tar.gz文件,第二条生成whl文件,这两个文件之后均会被上传。

在这里插入图片描述

0.3 上传pypi

0.3.1 pypi注册

官方网址:https://pypi.org

.pypirc文件创建
注册账号,为了在上传的时候不需要输入密码,需要创建.pypirc文件。在默认的用户目录下创建,例如我的目录为:

C:\Users\wu-xz\.pypirc

文件内容为:

[distutils]
index-servers=
    pypi

[pypi]
repository = https://upload.pypi.org/legacy/
username = wu-xz
password = ********* #这里输入你注册时使用的密码

0.3.2 使用twine工具

上传使用twine包进行,在cmd中运行

pip install twine

安装好包以后,使用twine检查需要打包的包,在setup.py所在的文件夹运行

twine check dist/*

若输出为PASSED,则说明没有问题;否则,根据报错检查错误,有可能会出现关于版本的错误,此时需要修改setup.py中的version

检查通过以后,运行以下命令

twine upload dist/*

然后会上传到.pypirc中指定的账号中。

注意:此过程中不能使用vpn,亲测vpn会中断连接。

登录pypi主页,查看是否上传成功;我的主页这样显示:

在这里插入图片描述

其中,README.md也正常显示了。

0.3.3 从pypi上安装pip包

通过以上步骤,我已经成功打包并且上传,下面通过pip安装:

#我的叫learnkeyhole
pip install -i https://pypi.org/simple/ learnkeyhole 

至此,整个流程就结束了。如果因为版本更新,你可以继续重复以上步骤更新版本。



以上内容纯属个人总结,难免有所差错,望批评指正!

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

伍贤知(肆)

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

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

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

打赏作者

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

抵扣说明:

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

余额充值