2013年4月30日星期二

Python中的module, library, package


Python中的module的简介

module,中文翻译为:模块
Python中的module,说白了,就是Python文件,而python文件一般后缀为py,所以就是你的xxx.py而已。

library简介

library,中文翻译为:库,也常称为:库文件
之所以此处不说是Python中的library,那是因为,本身library这个词,一般都是针对其他的编译型语言,比如C,C#等语言来说的。
常见的C/C#等语言中的library,一般指的就是:
静态的库文件:xxx.a
动态的库文件:xxx.dll

Python中的Package的简介

package,中文翻译为:包
Python中的package,可以简单的理解为,一组的module,一堆(相关的)module组合而成的;

Python中module和library之间的区别

对于library和module,说白了,都是提供了一定的功能供别人调用。
从这方面来说,也可以理解为:
Python中library等价于module;
只不过,Python中,很少说library,正常的话,都是说module;
所以,简而言之:
  • library多数都是指的是C,C#等语言中的库,库文件;
  • Python中,很少用library这个词;
  • Python中的“库”,“库文件”的叫法,叫做module,模块;
  • 不论你是Python的初学者还是高手,个人建议,都还是继续沿用,官方的,通用的叫法,使用 module这个词,而不要使用用library这个词; 
可以简单理解为:
  • module:单个的模块,一般是单个(偶尔为多个)python文件;
  • package:多个相关的module的组合。肯定是多个,相关的,Python文件的组合;package是用来把相关的模块组织在一起,成为一个整体的;


6.4. Packages
Package 是一组 modules ; Packages 机制使用 “dotted module names” 来结构化组织 Python 模块. 例如模块名 A.B 表示package A 中的模块 B. 就像 module 机制是用来分离不同代码文件中的全局变量名一样, Package机制是用来分离多个module名.

  1. package目录下的 __init__.py 文件用来向 python解析器声明这个目录包含的是一个 package 而不是普通的目录; 这用来防止目录名中含有逗号的情形。 最简单的, 放一个空 __init__.py 文件也行, 但是可以把 package 初始化代码放到 __init__.py 中或者设置 __all__ 变量, 后面会有详细描述.

  2. 用户可以从 package 中导入单个模块, 例如:

  3.     import sound.effects.echo

  4. 将导入子模块 sound.effects.echo, 需要注意的是,需要通过他的全名访问它内部的符号:

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

  6. 另一种导入子模块方式:
  7.     from sound.effects import echo
  8. 这样也可以导入子模块 echo, 并其可以不用 package 前缀来访问, 因此可如下调用他的内部符号:
  9.     echo.echofilter(input, output, delay=0.7, atten=4)
  10. 还有一种导入方法,直接就可以导入子模块中的函数或变量:
  11.     from sound.effects.echo import echofilter
  12. 这时可以直接调用子模块 echo 中的 echofilter() 函数:
  13.     echofilter(input, output, delay=0.7, atten=4)
  14. 注意使用 from package import item 这种方式时, 该 item 得是该package的子模块 (或 subpackage) 或是在该package中定义的其他名字, 比如函数, 类 或变量
  15.     1. import 语句首先确定该符号是否在package中定义过;
  16.     2. 若没有,则假定该符号是一个模块名并尝试去加载; 
  17.     3. 如果加载失败,则最后抛出一个 ImportError 异常.

  18. 不同的是,在使用 import item.subitem.subsubitem 这种语法时, 除了最末的项外,之前的项都得是package;最末项可以是一个模块或者package,但不能是类,函数  变量.
  1. 6.4.1. Importing * From a Package
  2. 理想情况下,使用 from sound.effects import * 将导入package 下所有的子模块.但实际上这会导致许多的副作用,因此 python 中采用了另一种方法:
  3.    用户显式指定 package 的子模块索引. 则 import 语句使用以下规则:
  4.       如果一个package 的 __init__.py 中定义了 __all__ 列表, 则 __all__ 中指定的所有模块将
  5.          被导入( 调用 from package import * 时). 因此 package开发者负责维护这个列表. 
  6.          当然开发也可决定不支持这种方式. 例如文件 sounds/effects/__init__.py 包含以下代码:
  7.          __all__ = ["echo", "surround", "reverse"]     
  8.          这意味着 from sound.effects import * 将导入在上面指定的那三个模块.

  9.       如果 __init__.py 中未定义 __all__ 变量, 则语句:
  10.          from sound.effects import * 
  11.       不会导入其下的子模块,而只保证该 package ( 为 sound.effects )导入到当前namespace中,并执行了 __init__.py 中的初始化代码,然后导入该 package 中定义的任何符号(在 __init__.py 中定义),包括之前用 import package.module 方式指定的模块. 看以下代码:
  12.         import sound.effects.echo
  13.         import sound.effects.surround
  14.         from sound.effects import *
  15. 这个例子中,模块 echo 和 surround 被导入当前 namespace.

  16. 记住,使用 from Package import 这种导入方法没有任何错误, 这是提倡的一种方式.


  1. 6.4.2. package 内部引用
  2.   package内部的子模块经常需要互相引用. 例如, 模块 surround 要使用 echo 模块. 实际上由于需要经常使用这种引用,  import 语句被设计为首先查找所属package,然后再查找标准模块搜索路径. 因此在 surround 模块中用 import echo 或 from echo import echofilter 来进行引用. 如果要导入的模块在当前package中没有找到, import 语句会在顶级的package 中查找该名字的模块.

  3. 当多个package被组织成结构化的 subpackages (就像上面例子中的 sound package ), 你可使用绝对绝对引用来引用相邻package中的子模块. 例如, 模块 sound.filters.vocoder 需要使用 sound.effects 包中的echo 模块, 就可以使用 from sound.effects import echo 来引用.

  4. 自Python 2.5开始, 除了用上面提到的显式相对导入外, 你还可以用 from module import name 形式的显式相对导入语句. 还可以用 . 开头的显式相对导入形式来指定是当前 package 还是父一级package.
  5. 例如,你可以使用:
  6.     from . import echo
  7.     from .. import formats
  8.     from ..filters import equalizer
  9. 注意,显式和隐式的路径都基于当前模块而言. 因为 main 模块的名字永远是 "__main__", 所以在Python应用程序中的 main 模块中需要一直使用绝对导入.

  10. 6.4.3Packages in Multiple Directories
  11. Packages 支持另一个特殊属性, __path__. 它被初始化为一个列表,每个元素为一个含有  __init__.py 的目录路径. 该变量可以修改,但会影响到该package中此后模块和子模块搜索.

  12. 这个特性较少使用, 它可用来对扩展某个package 中的模块集.

没有评论:

发表评论