一 包介绍

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

mmm/                #顶级包
├── __init__.py     
├── n             #子包
│   ├── __init__.py
│   ├── a.py
│   └── b.py
└── q.py      #子模块

  为什么要有包:包的本质是模块的模块的一种形式,包是用来被当做模块导入

强调!
1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错

2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包的本质就是一种模

  

二 包的使用

  2.1 导入包与__init__.py

    导入包时做了三件事:

    1、产生一个名称空间

    2、运行包下的__init__.py文件,将运行过程中产生的名字都丢到1的名称空间中

    3、在当前执行文件的名称空间中拿到一个名字,该名字指向1的名称空间

#包mmm
print('运行了。。。。')
x=1111
y=2222
def say():
    print('hello')

#运行文件
import mmm
print(mmm.x)
print(mmm.y)
mmm.say()
例如mmm.x和mmm.y中的x和y都是来自于mmm下的__init__.py,也就是说导入包时并不会导入包下所有的子模块与子包

    强调

1.关于包相关的导入语句也分为import和from ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则非法。可以带有一连串的点,如import 顶级包.子包.子模块,但都必须遵循这个原则。但对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。

# 例如:
from a.b.c.d.e.f import xxx
import a.b.c.d.e.f
# 其中a、b、c、d、e 都必须是包
2、包A和包B下有同名模块也不会冲突,如A.a与B.a来自俩个命名空间

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

 

  2.2 绝对导入与相对导入

    针对包内的模块之间互相导入,导入的方式有两种

    1、绝对导入:以顶级包为起始

#mmm下的__init__.py
from mmm import n

    2、相对导入:.代表当前文件所在的目录,..代表当前目录的上一级目录,依此类推:要强调的一点是相对倒数.的个数不能超过顶级包的目录

#mmm下的__init__.py
from . import n

    在包内使用相对导入还可以跨目录导入模块,比如a.py中想引用b.py的名字c

import也能使用绝对导入,导入过程中同样会依次执行包下的__init__.py,只是基于import导入的结果,使用时必须加上该前缀
如:import mmm.n

    针对包内部模块之间的相互导入推荐使用相对导入,需要特别强调:

    1、相对导入只能在包内部使用,用相对导入不同目录下的模块是非法的

    2、无论是import还是from-import,但凡是在导入时带点的,点的左边必须是包,否则语法错误

  2.3 from 包 import *

    ​ 在使用包时同样支持from pool.n import * ,毫无疑问*代表的是n下__init__.py中所有的名字,通用是用变量__all__来控制*代表的意思,他的使用方法和模块中的一样

  2.4 环境变量与包

     环境变量是以执行文件为准备的,所有的被导入的模块或者说后续的其他文件引用的sys.path都是参照执行文件的sys.path

      由于导入包的两种方式中相对导入只用在包的内部,所以我们使用的基本都是绝对导入,而绝对导入是以顶级包为基准的,每个人放包的目录又是不同的,因此最好的方法就是把包导入到环境变量中去。

import sys
sys.path.append(r'包的目录')
# 优化方案
import os
import sys

# print(__file__) # 当前文件的绝对路径
#dirname去除当前文件名后的路径
BASE_DIR=os.path.dirname(os.path.dirname(__file__))
sys.path.append(BASE_DIR)

  

  

 

原文地址:https://www.cnblogs.com/bk134/p/12591748.html