(接DAY45)

十一、模块和包

模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用 python 标准库的方法。

导入模块

想使用 Python 源文件,只需在另一个源文件里执行import语句,语法如下:

import module1[, module2[,... moduleN]

一个模块只会被导入一次,不管你执行了多少次import

指定导入模块

Python 的from语句让你从模块中导入一个指定的部分到当前命名空间中,语法如下:

from modname import name1[, name2[, ... nameN]]

例如,要导入模块 fibo 的 fib 函数,使用如下语句:

>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

这个声明不会把整个 fibo 模块导入到当前的命名空间中,它只会将 fibo 里的 fib 函数引入进来。

测试模块

一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用__name__属性来使该程序块仅在该模块自身运行时执行。

# Filename: using_name.py

if __name__ == '__main__':
   print('程序自身在运行')
else:
   print('我来自另一模块')

运行输出如下:

$ python using_name.py
程序自身在运行
$ python
>>> import using_name
我来自另一模块
>>>

每个模块都有一个__name__属性,当其值是'__main__'时,表明该模块自身在运行,否则是被引入。

包是一种管理 Python 模块命名空间的形式,采用"点模块名称"。
比如一个模块的名称是A.B, 那么他表示一个包A中的子模块B

使用模块的时候,不用担心不同模块之间的全局变量相互影响一样,采用点模块名称这种形式也不用担心不同库之间的模块重名的情况。

不妨假设你想设计一套统一处理声音文件和数据的模块(或者称之为一个"包")。
这里给出了一种可能的包结构(在分层的文件系统中):

sound/                          顶层包
      __init__.py               初始化 sound 包
      formats/                  文件格式转换子包
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  声音效果子包
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  filters 子包
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...

在导入一个包的时候,Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。
目录只有包含一个叫做__init__.py的文件才会被认作是一个包,主要是为了避免一些滥俗的名字(比如叫 string)不小心的影响搜索路径中的有效模块。
最简单的情况,放一个空的__init__.py就可以了。这个文件中也可以包含一些初始化代码或者为__all__变量赋值。

用户可以每次只导入一个包里面的特定模块,比如:

import sound.effects.echo

这将会导入子模块:sound.effects.echo。他必须使用全名去访问:

sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

还有一种导入子模块的方法是:

from sound.effects import echo

这同样会导入子模块:echo,并且他不需要那些冗长的前缀,所以他可以这样使用:

echo.echofilter(input, output, delay=0.7, atten=4)

还有一种变化就是直接导入一个函数或者变量:

from sound.effects.echo import echofilter

同样的,这种方法会导入子模块:echo,并且可以直接使用他的echofilter()函数:

echofilter(input, output, delay=0.7, atten=4)

使用from package import item这种形式的时候,对应的 item 既可以是包里面的子模块(子包),或者包里面定义的其他名称,比如函数、类或者变量。如果找到,抛出一个:exc:ImportError异常。

反之,如果使用形如import item.subitem.subsubitem这种导入形式,除了最后一项,都必须是包,而最后一项则可以是模块或者是包,但是不可以是类、函数或者变量的名字。

标签: 达内, 软件测试, Python

分类: 个人日志, 软件测试学习, Python, 学点技术

添加新评论