python:模块、扩展包、库的区别

404 阅读4分钟

什么是模块(module)

就是.py文件,里面定义了一些函数和变量,需要的时候就可以导入这些模块,然后使用里面的函数和变量

什么是扩展包(package)

扩展包是多个模块的组合。
如果一个文件夹下包括多个.py文件和一个__init__.py文件,那么这个文件夹就算是一个包。
python2版本需要__init__.py文件,pyhont3版本不需要__init__.py文件。

init.py文件就是专门用来帮助解释器区分所在文件夹到底是普通文件夹还是扩展包的。
你可能有疑问:为什么Python3之后不需要__init__.py了呢?可以自行百度
包可以嵌套到任何深度,只要相应的目录包含它们自己的__init__.py文件。

包:在模块之上的概念,为了方便管理而将模块(也就是.py文件)放在一个目录下。
   包目录下第一个文件便是 __init__.py,然后同级别的是一些其他的模块和子目录,
   假如子目录中也有 __init__.py,那么它就是这个包的子包了。
   常见的包结构:
      package_a
      ├── __init__.py
      ├── module1.py
      └── module2.py
      
      

什么是库

具有相关功能模块的集合。
这也是Python的一大特色之一,即具有强大的标准库、第三方库以及自定义模块。
标准库:就是下载安装的python里那些自带的模块,要注意的是,里面有一些模块是看不到的比如像sys模块,这与linux下的cd命令看不到是一样的情况。
第三方库:就是由其他的第三方机构,发布的具有特定功能的模块,贡献出来了,是开源的。在PYPI中,
         我们可以通过 pip install 安装
自定义模块:用户自己可以自行编写模块,然后使用。

吐槽一下:这三个概念实际上都是模块,只不过是个体和集合的区别

自己定义的模块和python自带的模块重名了

尽量不要重名。
一旦重名的话,import model_name时候到底是导入自定义的模块还是python自带的模块呢?

答案:简单来讲,python解释器会先查询内置模块看是否有需要导入的模块,
     再从sys.path所包括的目录下查询模块名字。
     所以,如果自定义模块名字与内置模块名字重合会被内置模块名字覆盖掉。
     但是注意内置模块和python标准库的模块还是不一样的,具体请看这个文章

总结

一般我们用import导入所需的包或者模块的时候,我们其实是不需要区分模块和包的区别的。
我自己之前也一直以为这两个词语是同一个意思。但是其实这是两个不同的概念。

任何以.py结尾的Python文件都是模块,模块的名字就是文件名(不加.py),不过有时候模块的名字也可以通过模块的__name__重新指定。

当我们导入模块或包时,Python创建的相应对象始终是模块类型。
也就是说无论是一个.py文件(模块)还是一个文件夹(包),一旦被导入之后,它的类型都变成了模块(读者可以通过type(module_name)来测试一下。
我自己通过python的debug模式显示了一下我导入的几个包,类型都是module)。

image.png

这意味着模块和包之间的区别仅在于文件系统级别,一旦被解释器导入到python中就没有区别了,都成为了模块(module)对象。
这也就是为什么我们一般使用过程中注意不到他们的区别。
换句话说,当.py文件和包含多个.py文件和__init__.py文件的文件夹没有被python解释器导入的时候,它们可以被叫做python的模块和包,但是一旦被导入,它们都只能叫做模块。

包也是特殊的模块,相比于普通模块,由于它是文件夹,所以多了一个__path的属性。
比如读者可以自己在电脑测试一下自己numpy的__path__是什么,下图是我的numpy的路径属性测试。

image.png