从全流程的角度来了解python包的使用,你也许会有不一样的认识

在python中,只要我们一谈到包或模块,基本默认说的就是包的导入和使用。也就是说只要我们知道包的名字,导入后知道怎么使用基本就可以了,但本人认为,我们仅仅了解的是包的一部分,若想对包有个整体的认识,我们还需知道包的整个制作和使用流程。

在这个圆环流程图中,实则并没有严格的前后顺序,你也可以先进行包的开发、制作、上传、下载、安装,最后再到包的导入和使用,同样也可以直接导入现成包直接使用 。那么接下来我们就从最基本的包开始介绍 。

1.模块和包(包的导入和使用)

谈到包,你就不得不知道模块 ,由于许多包就是由模块构成的 。所以,接下来我们就来了解下python中的模块 。

1.1 模块

1.什么是模块

所谓的模块,实则就是一个python ,以.py结尾的文件 ,文件内包含了类、函数、方法等 。

myproject
├─ __init__.py
├─ abc.py
└─ bcd.py

其中,abc和bcd就是python的模块 ,后续模块的导入和使用也是直接这两个名字即可 。

在python中,有许多现成的模块是可以直接使用的,列如os模块 。若使用其功能时只需要完成两步即可,分别是:

  1. 模块的导入
  2. 模块内函数、函数、类的调用

2.模块的分类

python中的模块,我们可以将其分为三类,分别是:

  • 系统自带模块 ,相当于安装python包就将这些模块自动安装上了,这一类型的模块在python的整个环境中全局有效,任何地方都可导入直接使用 。其中典型的模块以os为主 .
  • 第三方模块/包 ,使用时需要先下载安装并配置环境变量,在配置的环境变量内模块可以被导入使用 。这一类型的包或模块是我们最常用的,由于大多数情况下,系统模块都不能满足我们的需求 ,需要借助于大量的第三方模块/包才能完成工作 。
  • 自定义模块 ,项目内部开发的模块 ,可以在项目内部使用 ,超出项目内即无法使用 。

3.模块导入

在上面我们已经介绍到,若想要使用现成的模块,第一个步骤就是导入,在python中导入有两种方法,分别是:

# 第一种导入方式:
import 模块名

# 需求1:导入os模块 
import os

# 需求2 :导入自己编写的模块,abc  注意 : 导入自己编写的模块时需要注意路径 。
import abc 

# 说明: 通过这种方式导入的模块,使用时也需要加入模块的名字 ,列如os模块内有个getcwd()方法,在使用这个方法时,也必须是os.getcwd()才行 。

使用上面的导入方式有必定的弊端,列如说os内部有许多方法,但我只是使用其中的几个方法,但是通过import os导入后将os内所有方法和类全部导入,占用系统资源较大 ;其次就是每次使用具体方法或类时,必须前面加模块名 ,调用起来不太便捷 。以上的这些问题该如何解决呢 ?答案就是使用第二种导入方式 :from 模块 import 方法|类

# 第二种导入方式
from 模块名 import 成员名 

# 导入 os里的getcwd方法
from os import getcwd

# 说明 :通过这种方式导入后 ,使用getcwd()方法时直接调用getcwd即可。

从全流程的角度来了解python包的使用,你也许会有不一样的认识

4.模块路径搜索

无论是后面介绍的包,还是这里要介绍的模块,直接进行了导入操作 ,它就会先去找到这个模块/包 ,如果在指定的路径下搜索该模块,如果找到,则导入成功 ,否则导入失败 。具体搜索的先后顺序依次为:

  • 程序的当前路径
  • python的环境变量路径
  • python标准链接库路径

以上的路径组合起来就是sys.path所包含的路径 ,而python会选择在搜索路径中的第一个符合导入文件名的文件作为导入模块,找到后即停止后面的搜索 。所以若你自定义的模块和其它路径下的模块重名,你又想要用到自定义模块,就可以把自定义模块放在前面 。

同时还需要注意的是,自定义模块不能和系统模块重名,否则会报错 。

从全流程的角度来了解python包的使用,你也许会有不一样的认识

1.2 包

1.什么是包

包是一个包含多个模块的特殊目录,目录里有文件和目录的组合 ,其目录下有一个特殊文件__init__.py,这也是包和目录的最主要区别 。

myproject
├─ __init__.py
├─ mypack01
    ├─ __init__.py
├─ mydir
├─ ab.py
└─ bc.py


# 说明:
① . 其中myproject就是最外层的包 ,其中每个包下都会有个__init__.py的文件,这也是区别普通目录和包的最主要区别 。其中__init__.py中可以是空也可以有python代码 。
② . mypack01是子包 ,mydir是目录
③ . ab.pybc.py是包下的模块

其中包和模块的使用方式一样,同样需要先导入后调用(使用 ),这里就不再赘述。

从全流程的角度来了解python包的使用,你也许会有不一样的认识

2.__init__介绍

这里需要介绍下__init__这个特殊的文件,我们都知道它这个里面可以写代码,也可以不写 ?但是许多情况下我们并不知道,这个文件中到底该写什么代码 ?这个文件到底有什么作用呢 ?我们通过几段代码来展示它的作用 。

先看下两个模块(ab.py和bc.py)内的代码,

    # 文件:ab.py
    
    def div(a,b):
        return a // b
    
    def mul(a,b):
        return a * b
    # 文件 : bc.py
    
    def add(a,b):
        return a + b
    
    def min(a,b):
        return a - b

如果我想在test.py中调用以上两个文件中的函数,可以是如下的写法 :

    import mypack01.ab
    import mypack01.bc
    
    print(mypack01.ab.mul(3,4))		#输出:12
    print(mypack01.bc.add(3,4))     #输出 :7

通过以上的导入方法可以看到,能得到正确的结果 。接下来我们做个试验 ,导入时只写父包名 ,不写子包名 。具体如下图 :

从全流程的角度来了解python包的使用,你也许会有不一样的认识

只导入父包名就会报错 ,当鼠标移动到ab或bc上时, 提示了一句Cannot find reference 'bc' in __init__.py , 大体意思是在__init__.py中找不到bc . 于是我们在__init__.py中把这个模块导入 ,具体代码如下:

# mypack01包下的__init__.py 

import mypack01.bc
import mypack01.ab

从全流程的角度来了解python包的使用,你也许会有不一样的认识

以上的两个截图可以看到,test.py文件中的代码没变,而所变化的就是__init__.py . 那么这时__init__.py 到底起到了什么作用呢 ?结合着上面的提示 ,我们可以总结出:

在其它模块import后跟包名,实则导入的是init.py文件,也就是说只要你的代码导入其它包时,就会自动执行导入包下的__init__.py代码 。

那么,以上的结论在实际场景中到底有什么作用呢 ? 通过以上的代码肯定是看不出来的 ,我们可以想象一种场景, 假设我们有许多模块都要调用mypack01中的几个函数 ,是不是要在每个模块都要写几个导入语句啊 ,这个时候我们就可以将导入语句写到__init__.py代码中,这样是不是就节省了一部分代码呢 ? 这种场景不正是许多模块调用公共类库时会遇到的情形吗 ,所以 ,就可以使用__init__.py进行初始化一些导入 。

还有另外一种情况,可以用于from package import * , 这个*代表要把package包内的所有模块统统导入 。但有时候我们不希望部分模块被导入 ,由于部分模块只是被内部使用的,若被其它模块导入后,那就变为公共资源了 。这个时候怎么控制呢 ?答案就是在__init__.py中加入一个__all__变量列表 。

从全流程的角度来了解python包的使用,你也许会有不一样的认识

2.包的制作与上传

有时候我们开发的包也想供外界使用,你就可以把你的原始包制作成可供pip或者easy_install安装的包 。具体制作步骤如下:

  1. 在包对应的项目下创建必要的文件 ,分别为setup.py,LICENSE,README.md .

从全流程的角度来了解python包的使用,你也许会有不一样的认识

2.编写readme.md文件和setup.py脚本 。编写自己的README.md文件



### 1.包功能介绍

### 2.安装方法

### 3.参数说明

### 4.联系方式编写自己的setup.py

编写自己的setup.py

import os
import setuptools


# 读取readme文件
with open("README.md", "r",encoding='utf-8') as f:
 readme = f.read()

setuptools.setup(
 name="mypack", #包名称
 version="0.0.1", #版本
 author="Example Author", #包邮箱
 author_email="author@example.com", #作者邮箱
 description="A small example package", #包描述
 long_description=readme, #长描述,一般是readme ,打包到PiPy需要 。
 url="https://github.com/pypa/sampleproject", #项目URL
 packages=setuptools.find_packages(), #项目中需要的包
 classifiers=[ #程序的所属分类列表
 'Operating System :: Microsoft',
 'Operating System :: POSIX',
 'Operating System :: Unix',
 'Topic :: NLP',
 'Topic :: Software Development :: Libraries :: Python Modules',
 'Programming Language :: Python :: 3.5',
 'Programming Language :: Python :: 3.6',
 'Programming Language :: Python :: 3.7',
 'Programming Language :: Python :: 3.8',
 ],
)

3.进行打包 ,其中最常见的两种打包方式

# 以下的两个命令生成不同的格式 ,
python setup.py bdist_egg # 生成类似 mypack-0.0.1-py3.6.egg,支持 easy_install安装
python setup.py sdist # 生成类似 mypack-0.0.1.tar.gz,支持 pip 安装

从全流程的角度来了解python包的使用,你也许会有不一样的认识

以上截图分别是通过以上两个命令生成的的安装包 ,如果是本地用的话,就可以直接通过pip 或者easy_install安装 。但如果你想开源,你需要上传到PyPi

4.上传PyPi

  1. 在https://pypi.python.org/pypi上注册一个账号
  2. 在本地的用户目录下新建文件:.pypirc ,列如我的路径为:C:Userszhjy.pypirc 文件内容为:
[distutils]
 index-servers=pypi 
[pypi]
repository = https://upload.pypi.org/legacy/
username = yourname
password = youpassword

3.安装twine,pip install twine .

4.使用twine进行上传 ,twine upload dist/* .这样你的包就可以被全世界下载了 。

3.包的下载与安装

包的下载和安装主要用到pip ,这里就主要介绍下pip的使用 ,pip虽然使用它超级简单,但是它的参数超级多,许多情况下我们都会使用到 。

以安装pymysql为例

命令

说明

举例

pip –version

查看pip版本

pip install packagename

安装包

pip install pymysql

pip install packagename=0.9.3

安装指定版本

pip install pymysql=0.9.3

pip install packagename>=0.8.1

安装最低版本

pip install pymysql>=0.8.1

pip install –upgrade packagename

升级指定包

pip install –upgrade pymysql

pip uninstall packagename

卸载指定包

pip uninstall pymysql

pip search packagename

搜索指定包

pip search pymysql

pip show packagename

查看安装包的信息

pip show pymysql

pip list

列出以安装的包

pip list -o

列出可升级的包

pip freeze

列出以安装的包,包名==版本显示

pip freeze > 文件

导出到文件

pip freeze > a.txt

pip install -r requirements.txt

从文件中安装包

pip install packagename -i 镜像URL

指定镜像下载

pip install pymysql -i https://pypi.tuna.tsinghua.edu.cn/simple/

pip –default-timeout=600 install packagename

设置超时时间

pip install pymysql –default-timeout=600

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
歪了俩下的头像 - 鹿快
评论 共2条

请登录后发表评论