# 模块和包
[python模块与包的导入 - 沧澜猛兽 - 博客园](https://www.cnblogs.com/charles1ee/p/6560277.html)
## 什么是模块
一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀
>模块名字不能是中文
>在Python中一切皆对象,所以模块也是一个对象
## 为什么要使用模块
首先来说,运行python文件的方式一共有两种:
1. 一种是`脚本`运行
1. 命令行
2. 编辑器
2. 一种就是`模块`导入的方式
模块化的程序是指将大型的,笨重的编程任务划分成单独的,小巧的更易于管理的子任务或者模块的过程,然后在通过关联来创造完成一个大型的任务
### 模块化的优点:
简单性
可维护性
重用性
范围
![f56e5662.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/f56e5662.png)
## 部分知识点
## 在import的过程中发生了那些事情
import一个模块相当与执行了这个模块
一个模块不会被重复导入
如何去使用被导入模块中的名字
> 模块名.[模块中的变量名字]
在import
![76f2ebb5.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/76f2ebb5.png)
1. 寻找模块
2. 如果找到了,就开辟一块空间,执行这个模块
3. 把这个模块中用到的名字都收录到这个新开辟的空间中
4. 创建一个变量来引用这个模块的空间
> 1. 模块不会被重复导入
> 2. 模块和文件之间的内存空间始终是隔离的
> 3. 模块的名字必须是符合变量命名规范的
>
![7e5804fc.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/7e5804fc.png)
## 导入多个模块
![fd6fcace.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/fd6fcace.png)
> `注意`: PEP8 不允许这个写,必须一行导入模块
> 导入的话 也需要按照 内置 第三方模块 自定义模块的顺序
>
```python
import os # 内置
import django # 第三方
import my_module # 自定义
```
## 给模块 起别名
例如:
```python
import my_module as m
m.name
```
> 一旦起了别名 原名字就不可以使用了.
> 所以这里面my_moudle.name 就不可以使用了
方便\简化
用途
![6e82f09f.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/6e82f09f.png)
## 模块搜索路径
```python
import
```
目前正常的sys.path中除了内置\扩展模块所在的路径之外只有一个路径是永远不会出问题的
你执行执行的是这个文件所在的目录
一个模块是否能被导入,就看这个模块所在的目录在不在sys.path中
![e78c10ff.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/e78c10ff.png)
这样使用就可以使用了,虽然pycharm报错但是可以执行
![77f56e2b.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/77f56e2b.png)
## 两种运行一个py文件的方式
1.直接运行 cmd pycharm 脚本
2.导入 模块
`__name__` ==`__main__`
![fcc99e70.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/fcc99e70.png)
![1ead9eff.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/1ead9eff.png)
如果这个py文件既想被执行又可能被导入,这样就把想打印的内容就放在if下载
以后开发的使用,把一执行就打印出来的动作,放在if下载
## from ----import
![29810b98.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/29810b98.png)
![be0f4ab2.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/be0f4ab2.png)
![595a1ef9.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/595a1ef9.png)
all 和* 配合使用
使用方式:
`__all__` = ['xxxx','xxxx']
如果使用了`__all__`参数,那么后面要跟一个列表,然后里面以字符串的形式写入,代表着如果里面写入了一些名字,那么谁在通过import test from * 调用,只会调用`__all__`里面的名字,那么没有写在里面的名字就不会被调用
![b2d7e361.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/b2d7e361.png)
强制导入 仍然可以使用
## 补充内容
![5ca33664.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/5ca33664.png)
pyc只能提高程序的启动效率并不能提高程序的执行效率
### 模块的导入和修改
读到内存中的内容 修改没用
如下如
![f8f8d0eb.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/f8f8d0eb.png)
就算再次导入 也是无效的
![003c938f.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/003c938f.png)
如果一定要修改
![ccf88253.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/ccf88253.png)
不要reload 不会这个用的
### 模块的循环使用
![0a4509db.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/0a4509db.png)
程序设计问题
![6e01325c.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/6e01325c.png)
就会出现 报错
不能这样
![f4195596.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/f4195596.png)
即便是发生了循环引用,但没有发生报错,也会出现莫名的问题,所以绝对不用
### dir模块
可以获取这个模块中的所有名字
![60f1b0c7.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/60f1b0c7.png)
# 包
## 从包当中导入模块 ****
### 什么是包
含有一个__init__.py的文件夹就是一个包
包包中通常还有一些py文件
python2 没有 `__init__`的文件 两个文件不能互相导入
python3 无所谓
### 导入方法一
import
![79791e23.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/79791e23.png)
点的左边一定是个包
终点一定是个模块,具体到某个模块,不然就GG
### 导入方法二
from import
![86175f4f.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/86175f4f.png)
也可以这么写
![ea6db9a7.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/ea6db9a7.png)
## 直接导入包 **
![c26dea8e.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/c26dea8e.png)
### 绝对导入
导入包的过程中发生了什么事情
相当于执行了这个包的`__init__`.py文件
sys.path中的内容 永远是你当前工作的路径
### 导入包的相对导入 只能在包中使用
1
![31e09822.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/31e09822.png)
> `问题`:没有办法直接执行了
>说明:
>**无论是lmport 形式还是from...import形式,凡是在导入语句中(而不是在使用时)遇到的带点的,就说明这是包才有的导入语法,不能直接执行该文件了**
>
![e9e3e3b4.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/e9e3e3b4.png)
作为一个包来说 包里面的文件导入都应该 考虑到 sys.path 的文件的问题
## 一些说明
1. 关于包相关的导入语句也分为`import`和`from...import...`两种,但是无论哪种,无论什么位置,在导入时都必须遵循一个原则:**`凡事在导入时带点的,点的左边必须是一个包,否则非法`**。可以带有一连串的点,如item.subitem,subsubitem.但是都必须遵循这个原则
2. 对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数类(他们都可以用点的方式调用自己的属性)
3. 对于什么时候选择from..import..的场景
如果我们想直接使用name那么就必须使用这个了
```python
import sys
import glance.api.policy as gl
print(sys.path)
g1.get()
```
# 软件的开发规范
![410e88ef.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/410e88ef.png)
![988c96e9.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/988c96e9.png)
![19ccc77c.png](:storage/f89aeb57-736a-4373-b7d2-90a35ab6f911/19ccc77c.png)