001---包和模块

包和模块

模块

什么是模块?

  • 随着程序的功能越多,代码量越多。显然放一个文件不容易维护,为了编写可维护的代码。可以把函数分组,一个函数就是一个模块。
  • 在Python中,一个py文件就是一个模块(module)

使用模块有什么好处

  • 大大提高了代码的可维护性
  • 可以避免函数名和变量名冲突,每个模块有自己独立的名称空间。

分类

  • 内置模块:help(modules)可查看内置模块列表
  • 第三方模块:pip install module 联网安装
  • 自定义模块

模块调用

  • 一旦调用模块,相当于执行了模块里的代码
import os

import time, json

from decimal import Decimal

from decimal import Decimal as d

from django.views.decorators.csrf import csrf_exempt

from django.shortcuts import *
  • 模块查找路径:python解释器会按照列表顺序依次每个目录去匹配你要导入的模块名,匹配到了就不会往后找。
import sys
print(sys.path)

包是一种管理 Python 模块命名空间的形式,采用"点模块名称"。

比如一个模块的名称是 A.B, 那么他表示一个包 A中的子模块 B 。

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

这样不同的作者都可以提供 NumPy 模块,或者是 Python 图形库。

包的创建

创建包会自动生成__init__.py文件

![1561980301880](file:///C:/Users/86131/AppData/Roaming/Typora/typora-user-images/1561980301880.png)

回忆 创建一个tbjx模块发生的三件事:
将该tbjx文件加载到内存.
创建一个以tbjx命名的名称空间.
通过tbjx. 的方式引用tbjx模块的所有的名字.

创建一个包,也会发生三件事:
将该aaa包内 __init__py文件加载到内存.
创建一个以aaa命名的名称空间.
通过aaa. 的方式引用__init__的所有的名字.
包名就是 幕后指使的 init执行

包的引用方式

import 方式导入

aaa包与执行文件同级的情况
引用aaa包的__init__中的name
import aaa
print(aaa.name)#因为执行aaa 其实就是执行__inint__中内容


# 我想要引用 aaa包的m1文件的a变量
# 错误示例1:
import aaa
# 1. aaa的 __init__ 里面 写import m1
# 2. print(aaa.m1.a)
# print(aaa.m1.a)
# 报错原因: No module named 'm1'
# 分析报错原因: 模块找不到 内存,内置,sys.path三个地方找不到.
# m1 不在内存,不在内置,sys.path  会主动加载执行文件(包的使用.py)的当前目录. 而他不在

# 解决方式:
import aaa
# 1. 在执行文件写入 import aaa
# 2. aaa的 __init__ 里面 写 from aaa import m1#m1是要引入的文件名 aaa是包名
# 3. 然后在执行文件  aaa.m1.a
# print(aaa.m1.a) 引用 aaa包的m1的a
# print(aaa.m1.func1())#引用 aaa包的m1的func1()


# 如何在当前文件中,引用 aaa包的bbb包中__init__中 name.
# 1. 在执行文件写入 import aaa
# 2. aaa的 __init__ 里面 写 from aaa import bbb
# 3. 然后在执行文件 print(aaa.bbb.name)


# 如何在当前文件中,引用 aaa包的bbb包 a1.py文件中的 name
# 1. 在执行文件写入 import aaa
# 2. 在aaa包的__Init__ 写上 from aaa import bbb  (这样写 bbb包的__init__里面所有的名字都能引用)
# 3. 在bbb包的__Init__ 写上 from aaa.bbb import mb
4 print(aaa.bbb.a1.name)


# 首先 无论从哪里引用模块,import 或者 from  ... import ...
# 最开始的模块或者包名一定是内存,内置,sys.path中能找到的.(可参考bbb包中的 __init__)
# 直接import 为了让我们会使用 包里面的 __init__

from方式导入

# 第二类: 执行文件 通过 from ... import... 导入包以及包内的功能
# from ... import ...
# 通过这种方式不用设置__init__文件

我想要引用 aaa包的__init__ name
from aaa import name
print(name)

我想要引用 aaa包的 a1 文件中name
from aaa import a1
print(a1.name)

我想要引用 aaa包的 bbb包 __init__ name
from aaa.bbb import name
print(name)

我想要引用 aaa包的 bbb包 a1文件的中的name
from aaa.bbb import a1
print(a1.name)



重点
# from a.b.c import d
# c的. 的前面一定是包 
# import 的后面一定是名字 可以是文件,  并且不能 再有点   不能有点

# from aaa.bbb.m2.func1 import a  # 错误的
# from aaa.bbb import m2
# m2.func1()

相对导入与绝对导入

# from nb.m1 import f1,f2

# from nb.m2 import f3,f4

# from nb.m3 import f5,f6

# 目前为止,今天所看到的引用模块的方式都是绝对导入


# 相对导入: . ..  ......

from .m1 import f1,f2

from .m2 import f3,f4

from .m3 import f5,f6

from .dsb.ly import f7
需求
# 由于nb模块增加了很多很多功能,所以我们nb这个文件就要划整一个包,
# 无论对nb模块有任何操作,对于使用者来说不应该改变,极少的改变对其的调用. 像装饰器
第一版 文件变成包了 包与执行文件 在同一目录  
 用户 使用方式
# import nb
# nb.f1()
# nb.f2()
我们的解决方式 在aaa包的__init__ 加入
from nb.m1 import f1,f2#m1 中有f1 f2
from nb.m2 import f3,f4
from nb.m3 import f5,f6

第2版 包与 执行文件 不在同一文件 要想运行 必须在执行文件 添加sys 路径
import sys
sys.path.append(r'D:python22python 23 代码day19相对导入第2版 包在另一个文件下dir') #写死了 可以动态传

第3版 模块改名
在__init__ 里面改成相对导入
from .m1 import f1,f2#当前目录上一级
from .m2 import f3,f4
from .m3 import f5,f6
from .. import settings
原文地址:https://www.cnblogs.com/saoqiang/p/12176913.html