1. 把解决一类问题的模块放在同一个文件夹里,这个文件夹就是包;
2. 通过import或是from...import导入时必须遵循一个原则:
a> 凡是在导入时带点的,点的左边都必须是一个包,否则非法;
b> 导入后,使用时点的左边可以是包,模块,类,函数(它们都可以用点的方式调节用自己的属性);
c> from...import导入时,import后面不能带点,否则有语法错误,如from a import b.c是错误的语法;
d> from...import导入时,import后面可以接某个模块的一个方法,如from.glance.api.policy import get,该get是一个函数;
3. 一个包里的各包之间的__inint__.py导入包的模块时,可以使用绝对路径和相对路径,各有优缺点:
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/versions.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')) l.append(open('glance/db/__init__.py','w')) map(lambda f:f.close() ,l) import glance glance.api.policy.get()
glance/ #Top-level package ├── __init__.py #Initialize the glance package ├── api #Subpackage for api │ ├── __init__.py │ ├── policy.py │ └── versions.py ├── cmd #Subpackage for cmd │ ├── __init__.py │ └── manage.py └── db #Subpackage for db ├── __init__.py └── models.py 目录结构
#文件内容 #policy.py def get(): print('from policy.py') #versions.py def create_resource(conf): print('from version.py: ',conf) #manage.py def main(): print('from manage.py') #models.py def register_models(engine): print('from models.py: ',engine)
1> 使用绝对路径时:
a> 在包的内部或是包的外部,只要导入了对应包的模块(__init__.py文件),就可以使用模块的方式;
b> 不能挪动包到另一个目录下,因为使用的是绝对路径,挪动后绝对路径就不正确了;
I : 包的__init__.py文件的绝对路径的导入子包
II: 子包的__init__.py文件的绝对路径导入模块
III: 在包glance同级目录的脚本中导入包(外部导入包),包的子包模块的方法可以正常被调用:
执行结果:
IIII: 在子包内部导入其他子包的模块,可以正常调试其方法:
2> 使用相对路径时:
a> 可以随意挪动包,只要能找到包的位置,就可使用包里的模块方法;
b> 包里的模块如果想使用包的其他模块方法,首先也只能相对路径导入,而不能使用绝对路径导入;
c> 但是使用了相对路径,就不能在包内部直接执行,只能在包外执行方法;
I: 包的__init__.py文件,通过相对路径志入子包:
II:子包的__init__.py文件,通过相对路径导入子包模块:
(其它子的__init__.py文件导入模块同理: from . import manage from . import models)
III:在子包manage.py内部导入其他子包api,再调用该子包模块的方法(api.policy.get()),直接在这个子包manage.py执行脚本时会报错:
IIII: 在包glance的外部,导入包,直接执行这个study.py脚本,可以让子包中的 api.policy.get() 脚本 正常被执行:
3> 结合 __all__使用相对路径时:
(其它子包cmd和db的__init__.py的代码为: __all__ = ['manage'] 和 __all__ = ['models'] )
调用方法,与前面的相对路径相同: