【python基础篇】4. python模块

1 关于模块化编程

1.1 引言

之前有介绍过函数,函数是为了来封装公共的功能,当然也存在有大量公共的函数和变量,我们可以使用类和对象来对函数和变量进行统一的管理和调用。但是随着程序变得复杂,函数和类更加多了,我们可以怎么办呢?这时候“模块”就诞生了。模块一多,“包”就出现了。

包 > 模块 > 类和对象 > 函数

模块对应于python源代码文件。模块中可以定义变量、函数、类、普通语句。模块化编程将一个任务分解成多个模块。每个模块就像一个积木一样,便于后期的反复使用、反复搭建。

模块化编程的好处:

  1. 合理控制模块规模:按照逻辑性将代码尽可能的划分成多个子模块,方便客户端程序调用。将一个任务分解成多个模块,实现团队协同开发。
  2. 提高代码的可维护性:从代码的视角分析,变量越多,维护的难度越大。
  3. 提高代码可重用性:充分利用系统标准库或者自己编写的第三方库来为程序服务。

1.2 模块化编程流程

  1. 设计API,进行功能描述
  2. 编码实现API中描述的功能
  3. 在模块中编写测试代码,并消除全局代码
  4. 使用私有函数实现不被外部客户端调用的模块函数

API(Application Programming Interface),API没有规定具体的代码实现,只是提供访问模块的规范。API的设计应该包括多少信息,也没有强制的规定。一般包含函数名称、参数类型、返回类型等。

如以下可以查看math库的api文档

import math
help(math)

这里节选一部分

Help on built-in module math:

NAME
    math

DESCRIPTION
    This module provides access to the mathematical functions
    defined by the C standard.

FUNCTIONS
    sin(x, /)
        Return the sine of x (measured in radians).

    sinh(x, /)
        Return the hyperbolic sine of x.

    sqrt(x, /)
        Return the square root of x.

DATA
    e = 2.718281828459045
    inf = inf
    nan = nan
    pi = 3.141592653589793
    tau = 6.283185307179586

FILE
    (built-in)

当然,我们在python安装目录的docs目录下,也可以看到python的api文档(不确定使用conda方式安装的python下是否有)

1.3 模块的创建

  1. 功能描述与实现
#  student.py
"""本模块用于计算学生的成绩"""

def getTotalScore(scores):
    """计算总分"""
    return sum(scores)

def getAvageScore(scores):
    """计算平均分"""
    return sum(scores) / len(scores)
  1. 模块的导入与使用
    静态导入
    import xxximport math from xxx import xxfrom math import sqrt, from math import *
# main.py
import student  # 注意   只有在这一个
print(student.__doc__)  # 本模块用于计算学生的成绩
print(student.getTotalScore.__doc__) # 计算总分
print(student.getAvageScore.__doc__) # 计算平均分

from student import getAvageScore
print(getAvageScore([90, 80 ,70, 60]))

动态导入
使用 __import__ 函数导入

s = 'student'
m = __import__(s) #导入后生成的模块对象的引用给变量 m
print(m.getTotalScore.__doc__)

一般不建议使用__import__函数的方式引入,可以使用importlib库

import importlib
a = importlib.import_module('math')
print(a.pi)

导入一个模块的时候,模块中的代码就会被执行。如果再次导入这个模块,则模块中的代码不会被再次执行。Python这么设计的原因:模块更多的是定义变量、函数、对象等,这些并不需要反复定义和执行。

import student
print(dir(student)) # ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'getAvageScore', 'getTotalScore']
print(student.__name__)  # __name__ 内置属性

2 包

当一个项目中有很多的模块的时候,我们需要对模块进行组织。因此就有了包的概念,本质上『包』就是一个必须包含了__init__.py的文件夹。一般结构如下:
包中可以包含模块,也可以包含子包

├── a/
│   ├── __init__.py
│   └── a_module.py
├── b/
│   ├── __init__.py
│   └── b_module.py
│   ├── bb/
│	│   └── bb_module.py

2.1 包的引入

具体代码目录结构与代码
在这里插入图片描述

__init__.py文件中可以不写任何代码,但是必须存在,它定义了包的属性和方法,在导入模块之前,一定会先执行__init__.py中的内容,如果没有__init__.py文件,那么目录就仅仅是一个目录,而不是一个包。__pycache__为python缓存文件

a模块中的__init__.py文件

print("这是a模块中的__init__.py文件")
import a.a_module
import b.b_module
import b.bb.bb_module

from a import a_module
a_module.a_function()

from a.a_module import a_function
a_function()

# 输出
# 这是a模块中的__init__.py文件
# a_module
# b_module
# bb_module
# a function
# a function

2.2 sys.path 和模块搜索路径

当导入某一个模块文件的时候,python解释器一般会按照一下的路径搜索模块文件L:

  1. 内置模块
  2. 当前目录
  3. 程序的主目录
  4. pythonpath目录(如果已经设置了pythonpath的环境变量)
  5. 标准链接库目录
  6. 第三方库目录(site-packages目录)
  7. .pth文件的内容(如果存在)
  8. sys.path.append()临时添加的目录
    当任何一个python程序启动的时候,就将上面的搜索路径(除内置模块以外的路径)进行收集,放在sys模块的path属性中。如下
    /Users/maplewan/Desktop/AI-Go为当前目录,我们通过sys.path.append("./")将当前目录放入了sys.path
import sys
sys.path.append("./")
print(sys.path)
# 输出
'''
['/Users/maplewan/Desktop/AI-Go', '/Users/maplewan/anaconda3/lib/python311.zip', '/Users/maplewan/anaconda3/lib/python3.11', '/Users/maplewan/anaconda3/lib/python3.11/lib-dynload', '/Users/maplewan/anaconda3/lib/python3.11/site-packages', '/Users/maplewan/anaconda3/lib/python3.11/site-packages/aeosa', './']
'''

2.3 模块的发布和安装

模块开发完成之后,我们可以对外开放,其他开发者也可以以『第三方扩展库』的方式来使用我们的模块

对于以上的代码,我们可以在项目目录下面新建一个 setup.py 文件,如下

from distutils.core import setup
setup(
    name = 'mapleTest',
    version= '1.0',
    description= 'maple测试',
    author= 'maple',
    author_email= '1041709112@qq.com',
    py_modules= ['b.b_module', 'b.bb.bb_module'],
)

然后执行 python setup.py sdist,根目录下会出现一个dist文件夹,其中有mapleTest-1.0.tar.gz压缩包,我们可以使用python setup.py install 来将模块安装,我们可以在python安装目录lib/site-pacakages目录下发现mapleTest文件夹,说明安装成功。这种install的方式在最新的python版本中已经被废弃。报错如下

/Users/maplewan/anaconda3/lib/python3.11/site-packages/setuptools/_distutils/cmd.py:66: SetuptoolsDeprecationWarning: setup.py install is deprecated.
!!

        ********************************************************************************
        Please avoid running ``setup.py`` directly.
        Instead, use pypa/build, pypa/installer or other
        standards-based tools.

        See https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html for details.
        ********************************************************************************

!!
  self.initialize_options()
/Users/maplewan/anaconda3/lib/python3.11/site-packages/setuptools/_distutils/cmd.py:66: EasyInstallDeprecationWarning: easy_install command is deprecated.
!!

        ********************************************************************************
        Please avoid running ``setup.py`` and ``easy_install``.
        Instead, use pypa/build, pypa/installer or other
        standards-based tools.

        See https://github.com/pypa/setuptools/issues/917 for details.
        ********************************************************************************

!!
  self.initialize_options()
zip_safe flag not set; analyzing archive contents...

关于模块发布到PyPI 网站,可参考 https://zhuanlan.zhihu.com/p/682004873 (我也没做过这个)

3 库

python中米有对库具体的定义。模块和包侧重于代码的组织,有明确的定义。一般情况下,库强调的是功能性,而不是代码的组织。通常将某个功能的『模块的集合』,称为库

  1. 标准库:提供系统管理、网络通信、文本处理、数据库接口、图形系统、XML处理等额外的功能,如random, math, os
  2. 三方扩展库:pip, jieba, flask, pytorch

我们可以通过 pip install XX来安装库

如安装flask, pip install flask

  • 29
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值