提高代码可重用性,减少重复劳动--手把手带你实现Python自定义模块并上传到pypi,贡献自己创造的轮子为所有人使用,让Python开发更加简单
前言
我们都知道程序中可通过定义函数来减少工作量,提高代码的可重用性,从而提高我们的开发效率.我们一直import的是别人的模块,那如果我们需要使用自己的模块,或者开发一个自己的模块供别人使用,我们自己造轮子该怎么做呢?
我们实际的开发中,只在一个文件中编写代码是不太可能的,当开发大型项目的时候,一个文件过于臃肿,第一个是不利于阅读,代码可读性极差,还不利于团队协作开,所以这时候我们需要引入模块的概念.下面我们来了解什么是模块
什么是模块
我们对模块并不陌生,可能你已经使用多次,我们在使用import的时候就是使用到模块,比如我们在使用数组的时候会import numpy,我们在操作Excel数据时会import pandas.其实我们之前所有自己编写的代码片段都可以修改为一个模块,避免重复的劳动,提高开发的灵活性,接下来我们看下numpy包含的内容
我们可以使用一下代码输出numpy模块中定义的全部内容的名称.
运行结果部分截图:从截图中可以看出里面包含了很多我们常用的函数
下图的代码就是我们经常使用的numpy模块中的Arrayterator大数组的缓冲迭代器的源码:
接着我们详细分析import numpy是如何在程序中起作用的,当程序运行到import numpy的时候,便会开始寻找numpy模块,这一句就是告诉Python我们在程序中要使用该模块的内容.我们在使用之前已经使用pip install numpy安装过,已经把numpy安装到本地对应版本的Python中,在代码中我们无需指明模块目录,Python知道他的具体位置.
除了import,还有一条我们常用的引用的语句:from...import,他是将模块部分内容引到我们的程序中.比如下面这段代码:
程序将根号函数sqrt从math模块中引入程序并使用他,这种引入方式不必使用模块名加点符(比如:copy.deepcopy(data))。可以直接使用函数名,但是这也带来了名称冲突问题.这样只会引入模块的部分内容,减少了计算机的工作量,但是,一般来说我们在程序中应该尽量避免使用from...import语句,因为这条语句可能会导致程序中出现名称冲突并且让我们的程序更难被别人理解。
自定义模块
通过上述的讲解,大家对模块可能还是感觉有点神秘,如果你之前已经写过的案例或是练习的程序,那么在无形中你已经定义了很多模块。每一个独立的Python程序都可以当成一个模块。接下来我们使用代码段的方式正式创建一个模块并调用他。
也许大家学习其他编程语言的时候或者在数学中了解过斐波那契数列,甚至还使用其他语言实现过,这次咱们也使用Fibonacci数列练练手。以此为例创建一个自定义模块.文件名:myfirstmodule.py
代码中创建了两个函数,一个是实现斐波那契数列,另外一个printFibo(n)函数是控制输出数列个数的循环代码装入,最后添加了一行表示模块当前的版本号的变量,让该文件的内容更像一个模块。
接下来在模块文件myfirstmodule.py同目录下创建调用模块文件callModule.py,其内容如下:
运行结果如下:
调用的程序中,我们使用模块名加点调用模块中的变量和函数。那么我们Python是如何找到我们定义的模块呢?在创建callModule.py文件时我们提到过要在同目录下创建,这是因为当导入模块时Python会按照:"当前目录"->PYTHONPATH(就是安装Python的默认路径)下的每一个目录->默认路径(系统中的默认路径)这个顺序搜索模块直到找到该模块.
上传到pypi
准备
注册PyPI用户
- PyPI官网:https://pypi.org/
- GitHub:https://github.com/
- 安装git
Pypi是什么
pypi是一个python包的仓库,里面有很多别人写好的python库,你可以通过easy_install或者pip进行安装,方便用户更方面的使用你的代码模块。所以我们平时使用pip install 这个命令安装的模块都是从这里拉取的
注册完pypi需要验证邮箱!
代码上传到pypi的流程
将代码打包并上传到pypi上,大体上分为以下几步:
1、整理代码的目录结构,方便打包和python的import,为了方便引用,需要将代码模块变成一个包,所以需要将功能代码用目录来整合方便引用,并且需要创建__init__文件,__init__中可以没有内容,也可以在__init__文件中进行import(from .extractor import Document)操作,以减少整体模块引用时import的层数,避免错误。里面的myfirstmodule.py还是上面的写好的代码
2、功能模块的目录整理好后,就可以开始整理和添加发布到pypi上所使用的文件了
就是将原来的目录深移一层,文件夹名称可以根据自己意愿。然后在到第一层的目录下创建些特殊文件,具体你可以看看下面红色框里面的文件结构就大概明白了:
LICENSE文件是授权文件,比如: MIT license, APACHE license
README 文件使用过github的童鞋都不陌生,其实就是项目介绍和使用说明
setup.py文件才是重点,是python模块安装所需要的文件,它的格式如下图:
3、进行打包代码并上传到pypi
为了保证效果,在打包之前我们可以验证setup.py的正确性,打开命令行工具,然后定位到你的项目目录,比如我的是mymd;接着执行下面的代码
python setup.py check
3.1、写好的代码先上传到GitHub:
3.2、生成whl文件并上传给PYPI
进入你python环境,打开终端,进入到 mymd 文件夹下。我python环境是conda 环境,默认名称base
3.3使用python setup.py sdist bdist_wheel
命令进行打包,执行完成后会在 mymd 文件夹生成build、dist、xiaomicaiFibo_pip_fibo.egg-info三个文件夹
4、上传到pypi
使用twine上传代码,如果没有安装过twine需要先使用一下代码安装,安装命令如下:
pip install twine -i https://mirrors.aliyun.com/pypi/simple/
上传:twine upload --repository-url https://upload.pypi.org/legacy/ dist/*
执行这条命令输入用户名和密码,用户名密码是你注册PIPY时的用户名密码
上传成功如下图:
这时候进入pypi后台就可以看到自己上传的项目:
安装并测试我们上传的模块
安装我们自己的模块:
测试代码运行:
运行结果:
至此,我们已经已经完成了一次自定义模块以及把自己定义的模块上传到Pypi供别人使用的完整流程。光说不练假把戏,光看不做只是眼睛学会了,手没学会,动手实践起来吧~把自己的模块分享出来让大家开发变得更加简单!