模块与包

1、模块化程序设计思想

1.1 模块化程序设计的概念

• 如果程序中包含多个可以复用的函数或类,则通常把相关的函数和类分 组包含在单独的模块(module)中。这些提供计算功能的模块称之为模 块(或函数模块),导入并使用这些模块的程序,则称之为客户端程序。
• 把计算任务分离成不同模块的程序设计方法,称之为模块化编程 (modular programming)。使用模块,可以将计算任务分解为大小合理 的子任务,并实现代码的重用功能。

1.2 模块的API(Application Programming Interface)

  • 客户端使用模块提供的函数时,无须了解其实现细节;
  • 模块和客户端之间遵循的契约称之为API(Application Programming Interface,应用程序编程接口)
  • API用于描述模块中提供的函数的功能和调用方法
  • 模块化程序设计的基本原则先设计API(即模块提供的函数或类的功能 描述),然后实现API(即编写程序,实现模块函数或类),最后在客户 端中导入并使用这些函数或类;
  • 通过内置函数help(),可以查看Python模块的API;
  • 【例】通过内置函数help()查看math模块的API

>>> import math
>>> help(math)
Help on built-in module math:

NAME
    math

DESCRIPTION
    This module is always available.  It provides access to the
    mathematical functions defined by the C standard.

FUNCTIONS
    acos(...)
        acos(x)
        
        Return the arc cosine (measured in radians) of x.
    
    asinh(...)
        asinh(x)
        
        Return the inverse hyperbolic sine of x.
    
    cos(...)
        cos(x)
        
        Return the cosine of x (measured in radians).
    
    cosh(...)
        cosh(x)
        
        Return the hyperbolic cosine of x.
    
    degrees(...)
        degrees(x)
        
        Convert angle x from radians to degrees.
    
    fabs(...)
        fabs(x)
        
        Return the absolute value of the float x.
    
    factorial(...)
        factorial(x) -> Integral
        
        Find x!. Raise a ValueError if x is negative or non-integral.
    
    frexp(...)
        frexp(x)
        
        Return the mantissa and exponent of x, as pair (m, e).
        m is a float and e is an int, such that x = m * 2.**e.
        If x is 0, m and e are both 0.  Else 0.5 <= abs(m) < 1.0.
    
    fsum(...)
        fsum(iterable)
        
        Return an accurate floating point sum of values in the iterable.
        Assumes IEEE-754 floating point arithmetic.
    
    gamma(...)
        gamma(x)
        
        Gamma function at x.
    
    gcd(...)
        gcd(x, y) -> int
        greatest common divisor of x and y
    
    hypot(...)
        hypot(x, y)
        
        Return the Euclidean distance, sqrt(x*x + y*y).
    
    isclose(...)
        isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0) -> bool
        
        Determine whether two floating point numbers are close in value.
        
           rel_tol
               maximum difference for being considered "close", relative to the
               magnitude of the input values
            abs_tol
               maximum difference for being considered "close", regardless of the
               magnitude of the input values
        
        Return True if a is close in value to b, and False otherwise.
        
        For the values to be considered close, the difference between them
        must be smaller than at least one of the tolerances.
                
        -inf, inf and NaN behave similarly to the IEEE 754 Standard.  That
        is, NaN is not close to anything, even itself.  inf and -inf are
        only close to themselves.
    
DATA
    e = 2.718281828459045
    inf = inf
    nan = nan
    pi = 3.141592653589793
    tau = 6.283185307179586

FILE
    (built-in)

1.3 API设计

   • API定义客户端和实现之间的契约。API是一个明确的规范,规定“实现” 的具体功能是什么
   • API通常由两部分组成:可用函数的签名的精确规范,以及描述函数作 用的非正式自然语言描述API一般使用表格的形式,描述模块中的变 量、函数和类
   • 当编写一个新模块时,建议先设计API,然后实现模块

1.4 模块设计的一般原则

  • (1)先设计API,再实现模块
  • (2)控制模块的规模,只为客户端提供需要的函数。实现包含大量函数的模 块会导致模块的复杂性。例如,Python的math模块中就不包含正割函数、余 割函数和余切函数,因为这些函数很容易通过函数math.sin()、math.cos()和 math.tan()的计算而得
  • (3)在模块中编写测试代码,并消除全局代码
  • (4)使用私有函数实现不被外部客户端调用的模块函数
  • (5)通过文档提供模块帮助信息

1.5 模块的实现的概念

  • “实现”是指实现用于重用的函数或类的代码,模块的实现就是若 干实现函数或类的代码的集合,保存在一个后缀为.py的文件中;
  • 模块的实现必须遵循API规约,可以采用不同算法实现API,这为模 块的改进和版本升级提供了无缝对接,只需要使用遵循API的新的实 现,所有客户端程序无须修改即可以正常运行。

1.6 模块的客户端

  • 客户端遵循API提供的调用接口,导入和调用模块中实 现的函数功能;
  • API允许任何客户端直接使用模块,而无需检测模块中 定义的代码,例如可以直接使用模块math和random等。

1.7 模块化程序设计的优越性

  • 可以编写大规模的系统程序
  • 控制程序的复杂度
  • 实现代码重用
  • 增强可维护性

2、模块的导入与创建

2.1 模块导入方式(import)

方式一方式二
模块的导入import 模块名from 模块名 import 函数名 或:from 模块名 import *
导入示例import combinatorialfrom combinatorial import fac,comb 或者:from combinatorial import *
函数调用模块名.函数名函数名
函数调用示例combinatorial.fac(10)fac(10)

2.2 模块导入(import)

  使用import格式号入模抉吋,模抉中的所有内容都会被尋入到当前程序中,import的用法如下:
>>> import 模快1,模抉2,
  使用import可一-次辱入多个模抉,毎个模抉名之向使用“,"分割。在命令行中尋入某个模抉,用戸便可凋用指定模快中的任意方法,凋用模抉中方法的方式如下:
>>>模抉.方法()

2.3 模块导入(from 模块名 import 方法/类/对象)

  使用import语句导入模块后,每次调用模块中的内容时,都需要添加前缀”模块名.",若某些内容在导入模块的文件中使用的频率较高,亦或模块名较长,使用这种方法显然比较繁琐。为解决此问题,Python中提供 了"from…imo…"语句,该语句可导入模块中的部分内容,其用法如下:
>>> from模块import方法/类/对象
  以此语句导入的方法、类和对象等无需添加”模块名."前缀,可直接使用。以标准模块random中的randint方法为例,from…imp.r…的用法如下:

>>> from random import randint
>>> randint(1,100)
66

  from…i.pt…语句亦可一次导入多个方法(或类、对象) ,多个方法之间需用”,"隔开,示例如下:

>>> from random import randint, random
>>> randint(1,100)
96
>>> random()
0.03912063621688178

2.4 模块导入(from 模块名 import *)

  from…import *遵循from…import…语句的格式,其中通配符*指代指定模块中的全部方法,以random模块为例,在导入*之后,用户可使用random模块中的全部方法,示例如下:

 >>> from random import *>>> randint(1, 10)
 >>> random()
 0.6584572753461784
 >>> randrange(0, 10, 2)
 2

  使用from…import…语句可简化方法的调用方式,但若导入文件中存在与导入内容重名的方法、变量或类时,程序执行将会出错。因此,相对而言,使用import语句导入模块更为安全。

2.5 创建模块

  • Python模块对应于包含Python代码的源文件(其扩展 名为.py),在文件中可以定义变量、函数和类;
  • 在模块中,除了可以定义变量、函数和类之外,还可 以包含一般的语句,称之为主块(全局语句)。当运 行该模块,或导入该模块时,主块语句将依次执行。
➢ Python文件中的每个文件都可以做为一个模块存在,文件名即模块名。

>>> import os
>>> os.getcwd() #查看当前路径

>>> os.chdir("f:/python") #修改当前路径

搜索路径

>>> import sys
>>> sys.path() #查看搜索路径

>>> sys.path.append("f:/python") #添加搜索路径

3、模块的搜索路径

3.1 模块的搜索路径

模块搜索路径即Python搜索模块时的路径,这些路径存储于sys模块中的sys.path属性中,用户可先在解释器中导入sys模块,再查看sys.path的值,示例如下:

>>> import sys
>>> sys.path # 这里的路径根据Python安装路径而变化
['','E:\Python-3.5.2-embed-win32\Python35.zip' ,
 'E: \Python-3.5.2-embed-win32\DLLs' ,
 'E: \Python-3.5.2-embed-win32\lib',
 'E:\Python-3.5.2-embed -win32']

sys.path的本质是列表,因此用户可通过列表的内置方法append动态地向sys.path中添加模块所在路径。 假设将路径"E:\Python\workspace"添加到搜索路径中,其方法如下:
>>> sys . path append("E: \Python\workspace")

3.2 模块的导入顺序

  • 导入模块时,解释器按下列目录搜索路径和文件搜索顺序 查找并导入文件。目录搜索路径为:
  • (1)当前目录。启动交互式Python的目录,或Python主 程序位于的目录。
  • (2)操作系统环境变量PYTHONPATH中指定的目录。 • (3)Python标准库目录

3.3 模块搜索路径sys.path

  • sys模块的sys.path属性返回一个路径列表
  • 使用import语句导入模块时,系统自动从该列表的路径中搜索 模块,如果没有找到,则程序报错

4、包及模块的打包发布

  包是Python引入的分层次的文件目录结构,它定义了一个由 模块及子包,和子包下的子包等组成的 Python 的应用环境。 引入了包以后,只要顶层的包名不与别人冲突,那所有模块
都不会与别人冲突。
  每一个Python的包目录下面都会有名为__init__.py的特殊文件, 该文件可以为空文件,但是必须存在,它表明这个目录不是普通的目录结构,而是一个包,里面包含模块。
  为了更好地组织模块,开发人员通常选择将项目中的模块划分为包。简单来说,包(package) 是一个包含_init_ _ .py文件的目录,该目录中还包含一些模块或子包。 简单的包结构如下所示:

在这里插入图片描述

  包的存在使整个项目更富有层次,也可在一定程度上避免合作开发中模块重名的问题。包中的_ init_ .py 文件可以为空,但必须存在,否则包将退化为一个普通目录。

  用户可通过编辑子包中的_ init_ .py 文件,再以“ from包.子包import* ”的方式导入子包中的指定内容。若模块中未声明_ all_ 属性的内容, 使用form … import *导入模块时默认导入模块中的全部内容;与模块中的_ all _ 属性不同的是,若包中的_ init_.py未对_ all_ 属性做出声明,则使用from … import *导入的内容为空。

4.1 模块的打包发布

用户可将自己编写的模块打包为可安装的压缩包,分享给其它开发人员。将待发布的包放在与setup.py文件同级的目录中,目录结构如下所示:在这里插入图片描述

编辑setup.py脚本文件,steup.py文件中包含的内容如下:

>>> from distutils.core import setup
>>>setup(
         name=" itheima  #包名version="1.0"  #版本号
         description-"itheima belongs to itcast", #包的描述信息author= " itcast",#包的作者
         py_ modules-["suba.aa'," suba.bb ,’, 'subb.cc, 'subb. dd'])  #包中含有的模块

其中的setup为一个函数,包含5个参数,依次为:包名、版本号、描述信息、作者以及包中含有的模块,实际上setup函数中不只有这些参数,但这些参数也不是必需的,用户可有选择地进行设置。
在当前路径下打开命令行窗口,使用bulid命令构建模块,示例如下:

python setup.py build

经此操作后,当前目录中会创建一个名为build的文件夹,其中包含一个名为lib的目录, 该目录中存储了待发布模块的备份。build文件夹中的目录结构如下所示:
在这里插入图片描述
用户可通过sdist命令建立存放文件,示例如下:

python setup.py sdist

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值