关于模块和包的导入问题

1、包和目录的区别:

包和目录,形式上相似,都是用来装文件的容器,作为一个名称空间。
不同的是,当创建一个包时,会在包中默认创建一个空的__init__.py文件。
那么问题来了?这个__init__.py文件是干什么用的?
不管是哪种方式,只要是第一次导入包或者是包的任何其他部分,都会依次执行包下的__init__.py文件(我们可以在每个包的文件内都打印一行内容来验证一下),
这个文件可以为空,但是也可以存放一些初始化包的代码。
在讲模块时,我们已经讨论过了从一个模块内导入所有,此处我们研究从一个包导入所有

此处是想从包api中导入所有,实际上该语句只会导入包api下__init__.py文件中定义的名字,我们可以在这个文件中定义__all___:

在__init__.py中定义

x=10

def func():
print('from api.__init.py')

all=['x','func','policy']

1.1 当导入一个包时,会触发__init__文件的执行
如果在这个文件打印内置变量__name__,是所属包的包名 print("__name__",__name__)
该文件内可以通过包的绝对导入 (即以最顶层的包开始的路径) 和 包的相对导入
(即以 . 或 .. 开头的路径,导入模块 .
相对路径 和 绝对路径  导入包时的区别:
通过绝对路径,导包时,该__init__.py文件,可以单独运行(即以脚本方式执行)
当采用相对路径,导包时,该__init__.py文件。不能单独运行,只能通过其它文件,在导入该
__init__.py文件的包时,触发执行。

示例1:
from . import glancenew # 导入__init__.py文件所在路径下的文件,即该包下的文件
示例2:
from .api import policy # 导入__init__.py所在包下面的api包的policy模块

1.2 import xxx 不支持 . , .. 相对路径
from    import 支持. , .. ,但仅对于包而言
也就是说:相对导入 ,仅适用于包
C:\USERS\JIAYONG\PYCHARMPROJECTS\KNIGHT_SCHEMA\DAY26模块和包
│  01.py                  这个文件,去导入glance包  import glance
|                        这个时候,会触发glance包下的__init__.py 文件的执行  
|                        print(glance.glancenew.where) 
|						 print(glance.policy.where)
│  module2.py
│  包的导入测试.py
│  
├─.idea
│  │  day26模块和包.iml
│  │  misc.xml
│  │  modules.xml
│  │  workspace.xml
│  │  
│  └─inspectionProfiles
├─dir1
│  │  dir1.py
│  │  
│  ├─dir2
│  │  │  dir2.py
│  │  │  
│  │  ├─dir3
│  │  │  │  dir3.py
│  │  │  │  
│  │  │  └─__pycache__
│  │  │          dir3.cpython-36.pyc
│  │  │          
│  │  └─__pycache__
│  │          dir2.cpython-36.pyc
│  │          
│  ├─dir4
│  │  │  dir4.py
│  │  │  
│  │  └─__pycache__
│  │          dir4.cpython-36.pyc
│  │          
│  └─__pycache__
│          dir1.cpython-36.pyc
│          
├─glance  包
│  │  glancenew.py    where = " I am from glance/glancenew.py"
│  │  __init__.py    from . import glancenew    导入当前包下的 glancenew 模块
|  |                 from .api import policy   导入当前包 下的 api 包里的 policy 模块
|  |                 from glance import cmd   # 从glance包下导入 cmd 子包
|  |				 print(cmd.models.where)
│  │  
│  ├─api  包
│  │  │  policy.py        where = "I am from glance/api/policy.py"
│  │  │  versions.py
│  │  │  __init__.py
│  │  │  
│  │  └─__pycache__
│  │          policy.cpython-36.pyc
│  │          __init__.cpython-36.pyc
│  │          
│  ├─cmd 包
│  │  │  manage.py
│  │  │  __init__.py  from ..db import models 从当前__init__.py文件所在包 的父母包,下的db包 导入 models模块
│  │  │  
│  │  └─__pycache__
│  │          manage.cpython-36.pyc
│  │          __init__.cpython-36.pyc
│  │          
│  ├─db
│  │      models.py
│  │      __init__.py
│  │      
│  └─__pycache__
│          glancenew.cpython-36.pyc
│          __init__.cpython-36.pyc
│          
└─__pycache__
        module2.cpython-36.pyc
		
 # 基于上面的目录结构,再作一个实验
glance/db/__init__.py文件内容如下:
from .. import api                  # 导入api,触发api包下的__init__.py文件执行


glance/api/__init__.py文件内容如下:
import glance.api.versions    # 这种就是以绝对路径的方式导包中模块
 
 

 

 
 包的导入测试.py文件:内容如下:
from glance import db
print(db)  # <module 'glance.db' from 'C:\\Users\\jiayong\\PycharmProjects\\knight_schema\\day26模块和包\\glance\\db\\__init__.py'>

print(db.api) # <module 'glance.api' from 'C:\\Users\\jiayong\\PycharmProjects\\knight_schema\\day26模块和包\\glance\\api\\__init__.py'>
print(db.api.glance.api.versions)  # <module 'glance.api.versions' from 'C:\\Users\\jiayong\\PycharmProjects\\knight_schema\\day26模块和包\\glance\\api\\versions.py'>
print(db.api.glance.api.versions.where) # I am from glance/api/versions.py
posted on 2018-09-07 17:45  yellwonfin  阅读(165)  评论(0)    收藏  举报