我们在学习Python的过程中经常会听到一些名词,比如:模块、包、库、框架,这几个到底具体是指什么,有什么联系和区别?今天给大家来捋一捋。
首先这四个概念要分成两组:
模块(module)和包(package)是一组,在python中是有明确的含义的,而且和其他语言有略微的差异。 库(library)和框架(framework)是另一组,是编程中比较通用的概念,经常拿来比较。
先来说模块(module)和包(package)
其关系如下图所示:
这两个概念并不是大家所想的module就是py文件,package就是带__init__的文件夹。这个说法目前已经有些过时了。先看看官方文档怎么说的吧:
module
An object that serves as an organizational unit of Python code. Modules have a namespace containing arbitrary Python objects. Modules are loaded into Python by the process of importing.
https://docs.python.org/3/glossary.html#term-module
package
A Python module which can contain submodules or recursively, subpackages. Technically, a package is a Python module with an __path__ attribute.
https://docs.python.org/3/glossary.html#term-package
也就是说,模块(module)就是有命名空间的,python代码的一种组织形式。不一定是py文件,可以是.so,甚至可以是目录。而包(package)是一种可包含子模块或递归地包含子包的模块(module)。所以说包(package)也是一种模块(module)。 辨别到底是模块(module)还是包(package),就看这个模块(module)是否含有__path__的属性。
比如我们经常使用的re和json模块,可以看出,python对他们的定义都是module,json包含__path__ 而re没有。
>>> import re
>>> re
<module 're' from '/Users/xxx/anaconda3/lib/python3.7/re.py'>
>>> re.__path__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 're' has no attribute '__path__'
>>> import json
>>> json
<module 'json' from '/Users/xxx/anaconda3/lib/python3.7/json/__init__.py'>
>>> json.__path__
['/Users/xxx/anaconda3/lib/python3.7/json']
再说__init__.py的问题,在python3.3之后,PEP-420将包(package)分为了两种,一种是之前包含__init__.py的包,叫regular package。如果不包含__init__.py,python认为这个目录是namespace package。 也就是说 __init__.py不再是包(package)的必需品。比如我建立如下目录
> tree
some_path
├── namespace_pkg # no __init__.py, regular package
│ └── say.py
└── regular_pkg
├── __init__.py # has __init__.py, namespace package
└── say.py
其用法几乎一摸一样。
>>> import namespace_pkg
>>> namespace_pkg
<module 'namespace_pkg' (namespace)>
>>> import regular_pkg
>>> regular_pkg
<module 'regular_pkg' from '/some_path/regular_pkg/__init__.py'>
>>> import namespace_pkg.say
>>> namespace_pkg.say.hello()
Hello, This is Namespace Package!
>>> import regular_pkg.say
>>> regular_pkg.say.hello()
Hello, This is Regular Package!
虽然__init__.py不再是必需的,但是它让你有更多组织模块的机会,目前使用__init__.py还是主流。
再来说库(library)和框架(framework)
库(library)其实主要用来表示可重复利用的代码。别人写好了,直接拿过来用一下,我自己也可以写个自定义的库(library)。不管是复杂还是简单,只要是一个可重复使用的代码,都可以称为库(library)。比如大家常用的re,json,numpy,pandas。
其工作模式大概是下面左边这样的:
上面的模式中,是你调用库(library)来写程序,整体的流程,结构,标准都是你说了算。而框架(framework),则反过来,是框架(framework)在"调用"你。整体的流程,结构和标准你一般是不会改的,你所做的都是依赖于框架,在上面添砖加瓦。比如Django,Flask。
大致的流程是上图右边那样的。
以上就是对模块、包、库、框架的一些解释,希望对大家的理解有所帮助。
作者:看图学