包的详解

Posted hebbhao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了包的详解相关的知识,希望对你有一定的参考价值。

  在python中,包是一种管理模块的组织方式。凡是无论在import和from...import中遇到".模块名"的形式,这种带点的就是导入包的才有的导入语法。

  含有一个__init__.py文件的文件夹,就是一个包。导入包的本质其实就是导入__init__.py这个文件。

  例子:首先先部署好今天的环境:

技术分享图片
#例子:巧用map函数创建目录
‘‘‘
import os
os.makedirs(‘glance/api‘)
os.makedirs(‘glance/cmd‘)
os.makedirs(‘glance/db‘)
l = []
l.append(open(‘glance/__init__.py‘,‘w‘))
l.append(open(‘glance/api/__init__.py‘,‘w‘))
l.append(open(‘glance/api/policy.py‘,‘w‘))
l.append(open(‘glance/api/version.py‘,‘w‘))
l.append(open(‘glance/cmd/__init__.py‘,‘w‘))
l.append(open(‘glance/cmd/manage.py‘,‘w‘))
l.append(open(‘glance/db/models.py‘,‘w‘))
map(lambda f:f.close(),l)  

结果:
day26
    --glance
        --__init__.py
        --api
            --__init__.py
            --policy.py
            --version.py
        --cmd
            --__init__.py
            --manage.py
        --db
            --models.py
‘‘‘
包的层级

 1.从包中导入模块

  从包中导入模块的也有两种方式(无论哪种方式,都要谨记,点的左边必须是包)

  (1)import

  例如: 包名1.包名2.包名3.模块名

  (2)from...import

  例如:from 包名1.包名2 import 模块名

      from 包名1.包名2.模块名 import 变量名/函数名/变量名

 2.直接导入包

‘‘‘
情景1:
    既然导入包就是执行包下的__init__.py文件,那么尝试下在glance的
__init__.py文件中"import api",执行一下,貌似没有报错,在尝试下在包外导入,情况如何?
    import glance
    glance.api
ModuleNotFoundError: No module named ‘api‘

原因:
为什么还会报错呢?还记得sys.path,一个模块能不能被导入就看在sys.path中有没有路径,在哪里执行文件,sys.path永远记录是该文件的目录。
    (1)在glance的__init__.py文件中,sys.path的路径是:
   ‘E:\python_training_s1\old_boy_training\day26\glance‘
    所以能够找到同层级的api。
    (2)但是在day26_training.py文件中导入,此时sys.path的路径是:
    ‘E:\python_training_s1\old_boy_training\day26‘
    所以找不到不同层级的api,所以就会报NO module named ‘api‘
    
解决方法:
    使用绝对路径(绝对路径为当前执行文件的目录):
    (1)在glance包中的__init__.py中通过绝对路径的形式导入:
        “from glance import api”
    (2)这样在day26_training.py中执行,就能找到同层级的glance,再去找里面的api
    (3)同理,如果想使用api包中的模块,也要在api包中的__init__.py文件中导入"from glance.api import police,version"
    
绝对导入的缺点:
    如果以后包的路径发生了转移,包内的所有__init__.py文件中的绝对路径都需要改变
‘‘‘
# import glance
# glance.api
# import glance
# glance.api.policy.get()
#
# from glance.api.version import create_resource
# create_resource(‘dkfjk‘)

# from glance.api import policy
# policy.get()
‘‘‘
解决方式二:相对导入
    # .点表示当前目录
    # ..点表示上一级目录
(1)在glance包中的__init__.py中通过相对路径的形式导入:
     “from . import api”
(2)同理在api包中的__init__.py中通过相对路径的形式导入:
     “from . import policy,version”

优点:
    包发生路径转移,其中的相对路径都没有改变,所以不用逐个逐个修改。

缺点:
    但凡带着相对导入的文件,只能当做模块导入,不能作为一个脚本单独执行!!!
‘‘‘
# import glance
# glance.api.policy.get()

  


以上是关于包的详解的主要内容,如果未能解决你的问题,请参考以下文章

详解Android WebView加载html片段

14.VisualVM使用详解15.VisualVM堆查看器使用的内存不足19.class文件--文件结构--魔数20.文件结构--常量池21.文件结构访问标志(2个字节)22.类加载机制概(代码片段

Python中verbaim标签使用详解

18Linux源码包安装详解

包的详解

Yii2片段缓存详解