关于模块和包的导入问题
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
浙公网安备 33010602011771号