一、什么是包

  包就是一个包含有__init__.py文件的文件夹

二、为何要有包

  包的本质是模块的模块的一种形式,包是用来被当做模块导入

  1、产生一个名称空间
  2、运行包下的__init__.py文件,将运行过程中产生的名字都丢到1的名称空间中
  3、在当前执行文件的名称空间中拿到一个名字mmm,mmm指向1的名称空间

import mmm
from mmm import x

三、python3中与python2中的__init__.py的不同:

  如果下面存放了好多模块,当然每个模块都应该有自己自己的名字。我们需要把这些名字拿到__init__.py里面, 才能使用。python3中即便没有这个__init__.py文件也不会报错,pyhon2二中就会报错。是因为Python 3具有隐式命名空间包,允许它创建没有__init__.py文件的包。但是在python2中必须要有__init__.py这个文件。

四、包的使用

1、导入包和__init__.py

包属于模块的一种,因而包以及包内的模块均是用来被导入使用的,而绝非被直接执行,首次导入包(如import mmm)同样会做三件事:  

  1、产生一个名称空间
  2、运行包下的__init__.py文件,将运行过程中产生的名字都丢到1的名称空间中
  3、在当前执行文件的名称空间中拿到一个名字mmm,mmm指向1的名称空间

import mmm
from mmm import x

强调:

  1.关于包相关的导入语句也分为import和from … import …两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则非法。

  可以带有一连串的点,如import 顶级包.子包.子模块,但都必须遵循这个原则。但对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。

  2、包A和包B下有同名模块也不会冲突,如A.a与B.a来自俩个命名空间

  3、import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件

2、绝对导入和相对导入

  绝对导入,以包的文件夹作为起始来进行导入

import sys

print('==========>这是在被导入的__init__.py中查看到的sys.path')
print(sys.path)

from foo.m1 import f1
from foo.m2 import f2
from foo.m3 import f3

from foo.bbb.m4 import f4 # foo内有了一个f4

# # import foo.bbb.m4.f4 # 语法错误,点的左侧必须是一个包

  相对导入:仅限于包内使用,不能跨出包(包内模块之间的导入,推荐使用相对导入)

# .:代表当前文件夹
# ..:代表上一层文件夹

from .m1 import f1
from .m2 import f2
from .m3 import f3
from .bbb.m4 import f4

"""
强调:
1、相对导入只能在包内部使用,用相对导入不同目录下的模块是非法的
2、无论是import还是from import,但凡是在导入时带点的,点的左边必须是包,否则语法错误
3、绝对导入是没有任何限制的,所以绝对导入是一种通用的导入方式
"""

3、from 包 import *

  在使用包时同样支持from pool.futures import *

  * 代表的是futures下__init__.py中所有的名字,通用是用变量__all__来控制*代表的意思

  需要说明一点,包内部的目录结构通常是包的开发者为了方便自己管理和维护代码而创建的

  这种目录结构对包的使用者往往是无用的,此时通过操作__init__.py可以“隐藏”包内部的目录结构,降低使用难度,比如想要让使用者直接使用

import aaa

aaa.get()

需要操作sum下的__init__.py(提示: get在sum的aaa.py中):

from .aaa import get

五、软件开发的目录规范

Foo/
|-- core/  # 存放业务逻辑相关代码
|   |-- core.py
|
|-- api/  # 存放接口文件,接口主要用于为业务逻辑提供数据操作。
|   |-- api.py
|
|-- db/  # 存放操作数据库相关文件,主要用于与数据库交互
|   |-- db_handle.py
|
|-- lib/  #  存放程序中常用的自定义模块
|   |-- common.py
|
|-- conf/  # 存放配置文件
|   |-- settings.py
|
|-- run.py  # 程序的启动文件,一般放在项目的根目录下,因为在运行时会默认将运行文件所在的文件夹作为sys.path的第一个路径,这样就省去了处理环境变量的步骤
|-- setup.py  #安装、部署、打包的脚本。
|-- requirements.txt  #  存放软件依赖的外部Python包列表。
|-- README  # 项目说明文件

README的内容:

1、软件定位,软件的基本功能;

2、运行代码的方法: 安装环境、启动命令等;

3、简要的使用说明;

4、代码目录结构说明,更详细点可以说明软件的基本原理;

5、常见问题说明。